PHP 的 rand 函数有多不安全?

信息安全 密码学 php 随机的
2021-08-13 18:16:29

PHP 中有一些伪随机数生成器:rand()srand()mt_rand()mt_srand()你可以在这里查看他们的代码

我知道这些功能是不安全的,但它们有多不安全?

例如,如果这些函数用于生成反 CSRF 令牌,文件下载链接中的令牌,攻击者猜其他用户的令牌有多容易?他怎么能做到?

更新:论文I Forgot Your Password: Randomness Attacks Against PHP Applications似乎是有关该主题的规范读物,并包含对此问题的详细回复。但是,它很长而且很复杂,所以我想看一个更简短的摘录,它会指出或显示存在可以破坏这些功能的漏洞利用算法。

4个回答

PHP 的rand()生成器是基于系统实现的,通常是弱 LCG 或 LFSR(参见下面 Andrey 的评论)。有关为什么这些类型的生成器不好的更多信息,请查看非加密随机数生成器有多不安全?

mt_rand()函数使用Mersenne Twister,也好不了多少。只需观察 624 个值,即可确定内部状态和所有未来值

不要在任何需要加密强度随机性的情况下使用,包括 CSRF / 密码等效令牌。一个更好的选择是openssl_random_pseudo_bytes函数,或者从/dev/urandom. 您还可以考虑实施Blum Blum Shub,这是一个强大的(虽然很慢)PRNG。


编辑(2017 年 2 月):从 PHP7 开始,生成安全随机字节的正确方法是random_bytes()函数。有关各种语言的安全 RNG 的更详细建议,请查看这篇文章

现在 PHP 7 中有加密安全的伪随机生成器,包括random_intrandom_bytes可能值得检查一下。

您列出的所有 PRNG 都是不安全的。任何涉及安全(会话、令牌、机密)的东西都需要 CSPRNG。以下是合适的替代品列表:

  • mcrypt_create_iv() - 使用 *NIX 上的 /dev/urandom 和 Windows 上的内置加密平台。需要“mcrypt”扩展。
  • /dev/urandom - 需要 *NIX 主机。
  • openssl_random_pseudo_bytes() - 需要 'openssl' 扩展。
  • http://barebonescms.com/documentation/csprng/ - 一个跨平台的解决方案,它使用任何可用的东西以及一些生成真正随机数据的可信远程 Web 主机。

至于您关于论文的问题,您可能想出的生成随机字符串的任何算法之前都可能已经完成,并且源代码可能在某处可用。如果 PRNG 以微秒分辨率的当前系统时钟为种子,搜索空间将大大减少,只需要几十万次尝试。将其与可能数百种常用算法结合起来,您可能只需要几秒钟的 CPU 时间就可以对令牌进行逆向工程并与远程系统时钟同步。之后,应用程序的安全性就被破坏了。

我想问题是,有人愿意在那个级别破解你的网站吗?与尝试对令牌方案进行逆向工程相比,寻找 SQL 注入机会通常要容易得多。对于黑客来说,唾手可得的果实更可取。

这些都是不安全的。它们都不适合在 CSRF 令牌或任何其他需要加密强度的应用程序中使用。如果您想了解为什么不应该使用这些方法的更多详细信息,请参阅以下资源:

您应该改用random_bytes()or /dev/urandom

另请参阅使用 /dev/urandom 的 PHP 中更好的随机数