使用openssl_random_pseudo_bytes()来播种mt_rand()

时间:2017-01-18 22:37:13

标签: php cryptography password-generator

我尝试使用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进行播种。但是,我一直无法找到有关该主题的任何讨论。

1 个答案:

答案 0 :(得分:0)

根据documentation 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 explicitly stated不会产生加密安全值。

  

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

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

反建议

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

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

或者,this answer为使用OpenSSL作为CSPRNG的rand函数提供了基于PHP的安全实现,您可以使用它来代替random_int

相关问题