【问题标题】:Using openssl_random_pseudo_bytes() to seed mt_rand()使用 openssl_random_pseudo_bytes() 播种 mt_rand()
【发布时间】:2017-01-18 22:37:13
【问题描述】:

我正在尝试使用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 播种它。但是,我一直找不到关于该主题的任何讨论。

【问题讨论】:

  • 它只有在存储时才安全。充其量,我只会用它来生成(一次性)验证令牌,而不是用它来存储密码,如果是这样的话。
  • 对,这只是给用户一个随机密码。存储是完全不同的生物(散列等)。

标签: php cryptography password-generator


【解决方案1】:

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

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

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

反建议

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

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

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

【讨论】:

  • 谢谢@helmbert。我可以在函数中包含cryto_strong 签入。您对 Mersenne Twister 的评论确实是我问题的核心。我认为mt_rand 将是弱点,但我不知道它背后的科学。我会检查random_int。在问这个问题之前,我确实阅读了那个答案。我使用其中的一些想法编写了该函数的变体。感谢您为未来的读者提供链接。
猜你喜欢
  • 2015-04-07
  • 1970-01-01
  • 2012-07-06
  • 2011-06-24
  • 2010-11-21
  • 2012-12-14
  • 2012-08-27
  • 1970-01-01
  • 2014-12-27
相关资源
最近更新 更多