【问题标题】:PHP Generating secure random reset codes ($bytes and RandomLib)PHP 生成安全随机重置代码($bytes 和 RandomLib)
【发布时间】:2015-08-11 16:01:39
【问题描述】:

tl:dr 版本:

  • 第一个代码是否足够安全,可以在实际网站上使用?
  • 如何实现 RandomLib?请为初学者提供清晰的说明。

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

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

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

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

我在这个网站和其他网站上看到了很多关于 RandomLib https://github.com/ircmaxell/RandomLib 的建议,但我不知道如何使用它,而且我看到其他人在没有指导的情况下苦苦挣扎。我已下载 zip 并添加到我的网站文档中。我收到错误消息“致命错误:找不到类 'RandomLib\Factory'”,或者当我使用“require_once("RandomLib\factory.php");”链接到 factory.php 文件时我收到错误“致命错误:require_once(): 无法打开所需的 '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 返回一个布尔值,如果它是安全的,则返回 true,否则返回 false。 http://php.net/manual/en/function.openssl-random-pseudo-bytes.php

【问题讨论】:

  • 看看这个问题:stackoverflow.com/questions/6585649/…。这是另一种非常安全的方法。
  • 我写了一个小的php class 来帮助生成和处理这样的随机令牌。 bin2hex() 函数会使你的令牌比需要的更长,base62 编码更紧凑。

标签: php passwords reset


【解决方案1】:

首先,“黑客”一词有点不恰当。我知道这听起来很挑剔,但这对于理解问题非常重要。当您生成伪随机字符串时,您需要它们是不可预测的 - 这就是“安全”随机字符串和看起来像随机字符串之间的区别(即时间戳的哈希不是不可预测)。

话虽如此,您已经开始很好了 - openssl_random_pseudo_bytes() 是您实现目标的合适工具。 但是,根据环境的不同,可能还不够(这就是你没有找到明确答案的原因)。

问题是多方面的……

  • 该函数有第二个参数,可让您检查其输出是否真的“安全”,而您并没有进行检查。
  • 由于 OpenSSL 实施细节,大多数安全专家认为其他可能的随机来源更好(即mcrypt_create_iv() 或直接从 /dev/urandom 读取,但后者比较棘手)。
  • 由于它取决于环境(操作系统级资源),因此无法保证它在生产服务器上的安全性与在开发计算机上的安全性并且很容易忘记检查如果您将来将您的应用程序转移到另一台主机上。

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

然而,PHP7(截至本文发布时尚未发布)现在有一个 random_bytes() 函数,它为您抽象了所有这些问题并且有一个项目提供了一个用户-该功能的空间反向移植。它仍然是测试版(同样,正如我写的那样),但你应该明确地遵循它并在 1.0 版本发布后使用它。这里:https://github.com/paragonie/random_compat

【讨论】:

  • 感谢您的回复和解释。当人们像你一样解释它时,它真的很有帮助。我很高兴我已经从第一个功能开始。 PHP 7 听起来很有希望,因为希望像我这样的人更容易理解它。假设这是您的建议,我将使用函数的第二个参数更新原始帖子?在这个阶段,mcrypt_create_iv() 对我来说似乎有点复杂。在插入数据库之前,我确实使用 BCRYPT 对随机代码进行哈希处理,因此希望这将使其“足够安全”。再次感谢!
  • bcrypt 用于密码存储,您需要在其中防止暴力攻击,但这是因为密码相对容易被猜到。对于随机令牌,您不需要它(但您确实需要扩展它的长度,3 个字节是不够的;尝试使用 16+)。
猜你喜欢
  • 2021-06-18
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2012-05-06
  • 2021-09-03
相关资源
最近更新 更多