PHP 生成安全的随机重置代码($bytes 和 RandomLib)

PHP Generating secure random reset codes ($bytes and RandomLib)

tl:dr 版本:

很感谢之前有人问过这个问题,但似乎没有关于如何使用推荐方法的明确答案和指导。

我需要在用户忘记密码的情况下创建随机重置代码。然后将此重置代码添加到通过电子邮件发送给他们的 URL。当他们单击 URL 时,重置代码和电子邮件将与数据库中的代码和电子邮件进行比较,如果匹配,则会提供重置表单。

我第一次尝试创建代码很简单,但它是否足够安全?破解有多容易?我会要求人们在网站上注册,所以我需要确保系统安全。

<php?
$bytes = openssl_random_pseudo-bytes(3);
$reset_code = bin2hex($bytes);

我在这个网站和其他网站上看到了很多关于 RandomLib 的建议 https://github.com/ircmaxell/RandomLib 但我不知道如何使用它,而且我看到其他人在没有指导的情况下苦苦挣扎。我已经下载了 zip 并添加到我的网站文档中。我要么收到一条错误消息 "Fatal error: Class 'RandomLib\Factory' not found",要么当我 link 使用 "require_once("RandomLib\factory.php");"我收到一个错误 "Fatal error: require_once(): Failed opening required 'RandomLibactory.php' (include_path='.;C:\php\pear')"

require_once("RandomLib\factory.php");
$factory = new RandomLib\Factory;
$generator = $factory->getMediumStrengthGenerator(8, alphabet);

简而言之,如果 RandomLib 是最好的选择,如果有人可以为与我相似的初学者提供如何使用它的指导,那将会很有帮助。或者,如果第一个选项足够安全,我将保持原样。

更新:

正如下面 Narf 所指出的,创建随机字符串的函数缺少确保生成的字符串安全的第二个参数。

openssl_random_pseudo-bytes(3);

它应该是:

openssl_random_pseudo-bytes( 3 , $cstrong );

其中第二个参数 $cstrong returns 一个布尔值,如果安全则为真,否则为假。 http://php.net/manual/en/function.openssl-random-pseudo-bytes.php

首先,"hack"这个词有点不合适。我知道这听起来很挑剔,但这对于理解问题非常重要。当你生成伪随机字符串时,你需要它们是 不可预测的 - 这就是 "secure" 随机字符串和看起来像随机的字符串(即散列)之间的区别时间戳不是不可预测的)。

话虽如此,您的开端非常好 - openssl_random_pseudo_bytes() 是实现您的目标的合适工具。 但是,根据环境的不同,可能还不够(这也是你一直没有找到明确答案的原因)

问题是多方面的...

  • 该函数有第二个参数,允许您检查它的输出是否真的 "secure",而您没有检查它。
  • 由于 OpenSSL 的实现细节,大多数安全专家认为其他可能的随机性来源更好(即 mcrypt_create_iv() 或直接从 /dev/urandom 读取,但后者很棘手)。
  • 因为它取决于环境(OS 级资源),所以不能保证它在您的生产服务器上和在您的开发机器上一样安全 如果您将来将应用程序移动到另一个主机,很容易忘记检查。

RandomLib 的存在主要是因为上面列出的原因 - 它会为您的环境选择最合适的随机源,进行所有必要的检查并在没有 "secure" 随机源可用时触发错误。 RandomLib 的问题是……对不起,我帮不了你。我自己没有使用过它,但无论如何 - 您 post 编辑的错误消息清楚地表明您只是将错误的文件路径传递给 require()。如果您 post 将其作为一个单独的问题编辑 - 它会被关闭,因为它在 Whosebug 上被认为是题外话;你只需要自己把那个做好。

但是,PHP7(截至本 post 发布之时尚未发布)现在有一个 random_bytes() 功能,可以为您消除所有这些顾虑 and 有一个项目提供该功能的 user-space backport。它仍然是测试版(同样,在我写这篇文章的时候),但是你应该明确地遵循它并在 1.0 版本发布后投入使用。这里:https://github.com/paragonie/random_compat