17

在不依赖于典型 PHP 安装中很少包含的库的情况下,在 PHP 中生成加密安全的 32 字节盐的最佳方法是什么?

经过一番谷歌搜索后,我发现这mt_rand被认为不够安全,但我还没有找到替代建议。一篇文章建议阅读/dev/random但不仅这在 Windows 上不起作用;它也慢。

我希望在安全性和速度之间取得合理的平衡(即,生成 512 字节不应该像/dev/random通常那样需要 20 秒)

4

8 回答 8

23

这在 PHP 7 中更容易:只需用于$salt = random_bytes($numberOfDesiredBytes);生成盐。

无论如何,你需要盐做什么?如果是密码,只需使用password_hash()and password_verify()

于 2015-12-09T07:42:02.667 回答
9

注意mcrypt在 PHP 7.1 中已被弃用。跳到最新答案

您可能想查看mcrypt_create_iv().

于 2010-03-25T07:41:09.900 回答
8

注意mcrypt在 PHP 7.1 中已被弃用。跳到最新答案

您可以使用该函数mycrypt_create_iv(),因为 PHP 版本 5.3 它还使用 Windows 服务器上的随机源(不仅在 Unix 上)。在使用它之前,您应该检查该常量MCRYPT_DEV_URANDOM是否已定义。

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);

与随机不同,如果没有足够的熵可用,urandom 不会阻塞服务器。由于密码盐应该是唯一的(不一定是随机的),所以 urandom 对我来说似乎是一个不错的选择。

于 2012-08-24T15:51:37.603 回答
3

uniqueid不太适合生成随机字符串,因为它也是microtime基于的。CPU 周期通常比 microtime-tick 短得多,这可能导致循环内给定变量可能保持不变。将第二个参数“entropy”设置为true,

 uniqid('', true)

将提供增加的随机性。

要获得与大多数字符集很好兼容的随机字符串,可以将 base64 编码应用于mcrypt初始化向量函数mcrypt_create_iv

$length = 16;
base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM))
//> hlZuRJypdHFQPtI2oSFrgA==
strlen(base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM)))
//> 16

将字符字母减少到 2^6Bit 会增加大小,这在上面已经说明。

于 2013-09-19T15:57:48.537 回答
1

阅读/dev/urandom或使用openssl_random_pseudo_bytes().

于 2012-08-03T16:48:57.183 回答
0

看起来这个问题有一个可以接受的答案,但我只想在经过一些研究并阅读这个帖子后另外声明,如果你不把所有的鸡蛋都放在一个篮子里,你可能会增加一些安全性。

我可能建议不要仅仅依靠 PHP 来创建你的盐和散列你的密码。如果您让数据库完成部分工作,您可以进一步混淆您的解决方案。

有人建议只使用 password_hash() 和 password_verify()。虽然这些都是很好的方法,但我强烈建议坚持在这些方法之外加入盐的想法。

为了回答这个问题,盐可以是真正随机的任何东西,并且对用户来说是唯一的。只要您遵守这两条规则,您就可以在技术上按照您的意愿生成它。

几个很好的资源:

https://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right https://auth0.com/blog/adding-salt-to-hashing-a-better-way-to -存储密码/

于 2020-04-07T20:54:41.363 回答
-2

uniqid()应该可以用于此目的。

于 2010-03-25T08:04:48.050 回答
-7

我觉得microtime()够了。

奇怪的是,但我仍然对这个答案投了反对票。

虽然我得到的唯一解释是微时间是可以预测的。
这对我来说听起来很奇怪,因为盐总是被认为是众所周知的——所以,预测根本没有用。

于 2010-03-25T07:35:58.940 回答