1

我正在尝试使用openssl_random_pseudo_bytes并想知道它是否具有密码强度来构建一个简单的密码生成函数。

function randomPassword($length = 12) {
    mt_srand( hexdec( bin2hex( openssl_random_pseudo_bytes(256) ) ) );
    $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$&*-_=+.?';
    $pass = '';
    $alphaLength = strlen($alphabet) - 1;
    for ($i = 0; $i < $length; $i++) {
        $n = mt_rand(0, $alphaLength);
       $pass .= $alphabet[$n];
   }
   return $pass;
}

我会假设,如果函数中存在一个弱点,mt_rand无论使用openssl_random_pseudo_bytes. 但是,我一直找不到有关该主题的任何讨论。

4

1 回答 1

0

根据文档 openssl_random_pseudo_bytes,不能保证产生加密强的随机数据。但是,在它无法使用加密强 RNG 的不太可能的情况下,它至少会告诉你。这就是openssl_random_pseudo_bytes第二个参数的用途:

它还指示是否使用加密强算法来生成伪随机字节,并通过可选crypto_strong参数执行此操作。这种情况很少见FALSE,但某些系统可能已损坏或陈旧。

您可以传递此参数,然后检查其值:

$bytes = openssl_random_pseudo_bytes(256, $strong);
if (!$strong) {
    // handle error as necessary.
}

但是,与 相反openssl_random_pseudo_bytes明确声明mt_rand不产生密码安全值。

此函数不会生成加密安全值,并且不应用于加密目的。

我不是专家,但我怀疑使用安全随机数据播种 Mersenne Twister 是否会使生成的数据更加安全(如果有的话,可能只是第一个字节):

反建议

您没有说明您使用的是哪个版本的 PHP。如果您使用的是 PHP 7,random_int可能会为您提供一个很好的选择(它也明确声明是加密安全的):

for ($i = 0; $i < $length; $i++) {
    $n = random_int(0, $alphaLength);
    $pass .= $alphabet[$n];
}

或者,这个答案rand为使用 OpenSSL 作为 CSPRNG 的函数提供了一个安全的、基于 PHP 的实现,您可以使用它来代替random_int.

于 2017-01-18T23:06:41.447 回答