HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Password-generation function using custom seed

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
functionpasswordcustomseedgenerationusing

Problem

After reading an article on Skull Security mentioning the potential weakness of php's mt_rand function because of weak auto-seeding (http://ow.ly/4nrne), I decided to see what -- if any -- entropy I could find available from within php. The idea is to have enough (weak) sources that even if one or two are manipulated, lost or recovered, there's enough left to thwart brute force against the resulting passwords later.

Hopefully the result is both readable and usable, although I don't expect it to be production-quality.



Revision 1.01 adds a local secret.

Solution

I actually don't get the point of injecting so much system information into the mt_srand function. Looks like a total (and maybe even pointless) paranoia :)

But here you go with a cleaner code:

<?php
/**
* Random password generator
* v2.0
*/

define('APP_SECRET_KEY', 'qTgppE9T2c');

function randomPassword($length=10) {
  $charset = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789';
  $charsetSize = strlen($charset) - 1;

  // Seeding the generator with a bunch of different system data and the secret key
  mt_srand(crc32(md5(microtime())
    . getmypid()
    . md5(implode(getrusage()))
    . md5(implode(stat(__FILE__)))
    . memory_get_usage()
    . disk_free_space('.')
    . APP_SECRET_KEY)
  );

  $password = '';
  foreach (range(1, $length) as $_)
    $password .= $charset{mt_rand(0, $charsetSize)};

  return $password;
}

echo randomPassword(), "\n";


Maybe you'll like the more perverted superslow version which returns CRC32 of randomly ordered entropy each time you generate a new symbol.

<?php
/**
* Random password generator
* v2.1
*/

function randomPassword($length=10) {
  $charset = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789';
  $charsetSize = strlen($charset) - 1;

  $seeders = array(
    function () { return md5(microtime()); },
    function () { return md5(getmypid()); },
    function () { return md5(implode(getrusage())); },
    function () { return memory_get_usage(); },
    function () { return disk_free_space('.'); }
  );

  $randomSeed = function () use ($seeders) {
    shuffle($seeders);

    $entropy = '';
    foreach ($seeders as $seeder)
      $entropy .= $seeder();

    return crc32($entropy);
  };

  $password = '';
  foreach (range(1, $length) as $_) {
    mt_srand($randomSeed());
    $password .= $charset{mt_rand(0, $charsetSize)};
  }

  return $password;
}

echo randomPassword(), "\n";

Code Snippets

<?php
/**
* Random password generator
* v2.0
*/

define('APP_SECRET_KEY', 'qTgppE9T2c');

function randomPassword($length=10) {
  $charset = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789';
  $charsetSize = strlen($charset) - 1;

  // Seeding the generator with a bunch of different system data and the secret key
  mt_srand(crc32(md5(microtime())
    . getmypid()
    . md5(implode(getrusage()))
    . md5(implode(stat(__FILE__)))
    . memory_get_usage()
    . disk_free_space('.')
    . APP_SECRET_KEY)
  );

  $password = '';
  foreach (range(1, $length) as $_)
    $password .= $charset{mt_rand(0, $charsetSize)};

  return $password;
}

echo randomPassword(), "\n";
<?php
/**
* Random password generator
* v2.1
*/

function randomPassword($length=10) {
  $charset = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789';
  $charsetSize = strlen($charset) - 1;

  $seeders = array(
    function () { return md5(microtime()); },
    function () { return md5(getmypid()); },
    function () { return md5(implode(getrusage())); },
    function () { return memory_get_usage(); },
    function () { return disk_free_space('.'); }
  );

  $randomSeed = function () use ($seeders) {
    shuffle($seeders);

    $entropy = '';
    foreach ($seeders as $seeder)
      $entropy .= $seeder();

    return crc32($entropy);
  };

  $password = '';
  foreach (range(1, $length) as $_) {
    mt_srand($randomSeed());
    $password .= $charset{mt_rand(0, $charsetSize)};
  }

  return $password;
}

echo randomPassword(), "\n";

Context

StackExchange Code Review Q#1494, answer score: 2

Revisions (0)

No revisions yet.