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