PHP 的 mt_rand 函数如何生成种子?

15

我知道PHP的 mt_rand()不应该用于安全目的,因为其结果不具备密码学强度。 然而,很多PHP代码仍然这样使用,或者在更好的随机源不可用时使用它作为后备。

那么情况有多糟糕? mt_rand使用哪些随机源进行种子生成?而且,在密码应用中,mt_rand还存在其他安全问题吗?

1个回答

19
在PHP 5.4中,如果mt_rand第一次使用时自动种子化(参见PHP源代码),则种子值是当前时间戳、PHP进程PID和PHP内部LCG产生的值的函数。我没有检查以前版本的PHP源代码,但文档表明从PHP 5.2.1开始使用这个种子算法。 mt_rand背后的RNG算法是Mersenne Twister。谈论它有多糟糕实际上没有意义,因为已经清楚记录下来(不幸的是,没有在PHP文档页面上),它是完全不适用于加密应用。如果你想要加密强度的随机性,请使用已记录的加密强度生成器。 更新: 您还可以查看来自crypto.SE的此问题

你可能会感兴趣的是,在FreeBSD、OpenBSD和OSX中,/dev/random/是由Fortuna算法填充的,这个算法是具有密码学安全性的。 - Leigh
根据PHP源代码,似乎PHP的内部LCG也是使用时间和pid作为种子,因此它并没有增加太多的随机性。那个链接到crypto.stackexchange也非常有启示性。 - JanKanis
@Jon:显然,使用LCG来种子化MT可以改善生成数字的分布,这是一个好主意。然而,对于加密目的来说,这并不提供任何额外的熵。如果攻击者知道PID和时间戳,他同样可以轻松预测生成的随机数。 - JanKanis
@NikiC:有很多应用需要加密安全的随机数(我所说的加密安全是指攻击者无法预测值),例如生成会话ID或CSRF令牌。盐生成确实不是其中之一。 - JanKanis
@Somejan:确实如此:加密密钥、随机密码、会话密钥、流初始化向量、nonce、安全唯一标识等等……我不同意@NikiC的“几乎全部”的说法。你用来防止彩虹攻击的盐不需要是随机的,但它们必须是唯一的,而PHP中mt_rand()的所有漏洞让我即使只是为了那个也感到不安。 - user213154
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接