如何用PHP生成密码安全的随机数?(复制)

时间:2022-11-25 19:37:52

Possible Duplicate:
Secure random number generation in PHP

可能的重复: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?

我们需要生成一个密码随机字符串作为身份验证标记,它将绑定到数据库中的会话数据。我们正在使用PHP,它似乎没有内置合适的随机数生成器。如何使用php生成N长度的密码安全随机字符串?

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

还要注意,由于我们的应用程序的性质,shell_exec不在讨论范围之内。

3 个解决方案

#1


-7  

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

函数呢?文档中有一个如何将其用于cookie /session的示例。

#2


4  

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

根据您的平台,您可以使用/dev/urandom或CAPICOM。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:

如果为了安全或密码目的需要一些伪随机位(例如,g)。,对于块密码来说是random IV,对于密码哈希来说是random salt) mt_rand()是一个很差的来源。在大多数Unix/Linux和/或MS-Windows平台上,您可以从OS或系统库中获得更高级别的伪随机比特,如下所示:

<?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."

NB:一般来说,将读/dev/urandom的尝试和在代码中访问CAPICOM的尝试放在一起都是安全的,尽管每个尝试在另一个平台上都将无声地失败。把它们都放在那里,这样你的代码就更容易移植了。

#3


-4  

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

在我的头顶上:利用微时间,将它乘以微时间% 100,并在收到结果的sha1上做很少的randoms。

#1


-7  

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

函数呢?文档中有一个如何将其用于cookie /session的示例。

#2


4  

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

根据您的平台,您可以使用/dev/urandom或CAPICOM。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:

如果为了安全或密码目的需要一些伪随机位(例如,g)。,对于块密码来说是random IV,对于密码哈希来说是random salt) mt_rand()是一个很差的来源。在大多数Unix/Linux和/或MS-Windows平台上,您可以从OS或系统库中获得更高级别的伪随机比特,如下所示:

<?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."

NB:一般来说,将读/dev/urandom的尝试和在代码中访问CAPICOM的尝试放在一起都是安全的,尽管每个尝试在另一个平台上都将无声地失败。把它们都放在那里,这样你的代码就更容易移植了。

#3


-4  

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

在我的头顶上:利用微时间,将它乘以微时间% 100,并在收到结果的sha1上做很少的randoms。