我总是被告知在给密码加盐时我应该使用openssl_random_pseudo_bytes
。
但我真正想知道的是,它使加密安全的原因。 rand
,mt_rand
和openssl_random_pseudo_bytes
之间的内部差异是什么?
提前致谢。
答案 0 :(得分:13)
差异很简短:
rand
使用libc随机数生成器(source),它取决于系统并且通常不具有加密安全性mt_rand
使用已知算法Mersenne Twister,因此得名;这是一种快速算法,可以生成分布良好但不具有加密安全性的randoms openssl_random_pseudo_bytes
直接调用OpenSSL system for cryptographically-secure randoms(但请参阅完整说明中的警告)这些属性也列在下表中:
rand
对于rand
,请在mt_rand
中说明:
许多旧libcs的随机数生成器具有可疑或未知的特征并且速度很慢。
因此,对于rand
,您必须查看您的libc以确定实际使用的随机数。它在Mersenne Twister网站上声明它现在应具有可比较的速度,但它的特性取决于系统。它也没有说明它是如何播种的,这意味着你可以将它用于游戏等,但不能用于其它方面。
mt_rand
Mersenne Twister是一种众所周知的算法,可以生成相当好的分布随机数。它有一个很长的周期,这意味着在遇到前一个状态之前需要很长时间(如果发生这种情况,它会保持循环,循环的大小称为句点)。 MT不安全,因为有足够的数据可以重建其安全状态。这意味着如果您首先生成密钥,然后将该算法用于其他内容,则攻击者可以在给定足够输出的情况下重新创建密钥。此外,在创建时使用非安全种子作为系统时间。
openssl_random_pseudo_bytes
OpenSSL的随机数生成器通常是加密安全的(见下面的注释);这意味着在给定发电机输出的情况下不可能重新计算内部状态。
OpenSSL的伪随机数生成器是使用散列函数构建的,当前是MD5,它应该对于生成随机数仍然是安全的。它分布均匀,并且 - 像MT算法一样 - 具有较高的周期。 OpenSSL的rand
比MT慢得多,但它的速度应该还要快。
它比OS随机数生成器具有优势,它不需要额外的线程或系统调用。 OpenSSL使用操作系统随机数生成器(+可能的其他源)来创建初始种子。 OS随机生成器通常是可用的最佳随机数生成器,因为操作系统可以访问不直接可用于库和应用程序的熵源。
警告:在OpenSSL的Wiki上声明:
RAND_pseudo_bytes
返回伪随机字节,这些字节可以加密强大。如果字节加密强,则函数返回1
,否则返回0
。如果您的应用程序具有高完整性要求,则不应使用RAND_pseudo_bytes
。
PHP函数反映了这一点:
如果传入函数,这将包含一个布尔值,用于确定所使用的算法是否为“加密强度”,例如,对于使用GPG,密码等是否安全
TRUE
如果它确实如此,否则FALSE
这意味着它可能仍然不安全,例如长期钥匙。
警告#2 :其他见解表明,无论返回值,OpenSSL的PRNG可能并不总是安全。因此在选择OpenSSL之前应该特别小心。