6

Possible Duplicate:
Secure random number generation in PHP

We need to generate a cryptographically random string to use as an authentication token, which will be tied to session data in the database. We are using PHP, which doesn't appear to have a suitable random number generator built-in. How can we generate a cryptographically secure random string of N length using php?

Also note, due to the nature of our application, shell_exec is off the table.

Community
  • 1
  • 1
Travis
  • 4,018
  • 4
  • 37
  • 52

3 Answers3

4

Depending on your platform, you may use /dev/urandom or CAPICOM. This is nicely summarized in this comment from Mark Seecof:

"If you need some pseudorandom bits for security or cryptographic purposes (e.g.g., random IV for block cipher, random salt for password hash) mt_rand() is a poor source. On most Unix/Linux and/or MS-Windows platforms you can get a better grade of pseudorandom bits from the OS or system library, like this:

<?php
// get 128 pseudorandom bits in a string of 16 bytes

$pr_bits = '';

// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
    $pr_bits .= @fread($fp,16);
    @fclose($fp);
}

// MS-Windows platform?
if (@class_exists('COM')) {
    // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
    try {
        $CAPI_Util = new COM('CAPICOM.Utilities.1');
        $pr_bits .= $CAPI_Util->GetRandom(16,0);

        // if we ask for binary data PHP munges it, so we
        // request base64 return value.  We squeeze out the
        // redundancy and useless ==CRLF by hashing...
        if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
    } catch (Exception $ex) {
        // echo 'Exception: ' . $ex->getMessage();
    }
}

if (strlen($pr_bits) < 16) {
    // do something to warn system owner that
    // pseudorandom generator is missing
}
?>

NB: it is generally safe to leave both the attempt to read /dev/urandom and the attempt to access CAPICOM in your code, though each will fail silently on the other's platform. Leave them both there so your code will be more portable."

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
codehead
  • 2,077
  • 16
  • 20
  • Thanks - I do believe this is the best way, since /dev/urandom uses a variety of entropy sources, rather than just the system clock. In my case, however, we will not be able to use fopen in this manner because we're basically working in a sandboxed environment. – Travis Oct 11 '09 at 15:44
  • 1
    UPDATE: From [Windows Platform SDK Redistributable: CAPICOM](http://www.microsoft.com/en-us/download/details.aspx?id=25281) - "CAPICOM is excluded from the Windows SDK beginning with the Windows SDK for Windows 7, and although the distributable will run on 32-bit versions of Windows 7 and Windows Server 2008 R2 operating systems, its use is not recommended. For more information, see [Alternatives to Using CAPICOM](http://msdn.microsoft.com/en-us/library/windows/desktop/cc778518%28v=vs.85%29.aspx)" – Herbert Jun 26 '12 at 17:46
-4

Off the top of my head: take micro time, multiply it by microtime % 100 and do few randoms on sha1 of received result.

Eimantas
  • 48,927
  • 17
  • 132
  • 168
-7

what about uniqid? docs have an example of how it can be used for cookies/sessions.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • This seems to be the best approach - when combined with mt_rand as described in the manual. – Travis Oct 11 '09 at 16:13
  • 8
    uniqid is not cryptographically secure, it is designed specifically to never return the same number twice, since it is based on the system clock it does however have a quite low entropy if only an attacker know approximately when it was generated. – aaaaaaaaaaaa Nov 26 '10 at 19:24
  • @ebusiness: OP doesn't actually need cryptographically secure function. and `uniqid` is perfect for his case. – SilentGhost Nov 26 '10 at 21:27
  • 8
    As far as I can tell we are talking about a session id, if you can guess someones session id you will gain their privileges. How do you justify that unguessable random is not required? – aaaaaaaaaaaa Nov 26 '10 at 23:28