在 PHP 中生成盐
在 PHP 中生成加密安全的 32 字节盐而不依赖于典型 PHP 安装中很少包含的库的最佳方法是什么?
经过一番谷歌搜索后,我发现 mt_rand
被认为不够安全,但我还没有找到替代的建议。一篇文章建议从 /dev/random
读取,但这不仅在 Windows 上不起作用;它也非常慢。
我想要安全性和速度之间的合理平衡(即,生成 512 字节不应该花费 20 秒,就像 /dev/random
通常那样)
What's the best way to generate a cryptographically secure 32 bytes salt in PHP, without depending on libraries seldom included in typical PHP installations?
After some googling I discovered that mt_rand
is not considered secure enough, but I haven't found a suggestion for a replacement. One article suggested reading from /dev/random
but not only this won't work on windows; it is also very slow.
I want a reasonable balance between security and speed (ie, it shouldn't take 20 seconds to generate 512 bytes, like /dev/random
usually does)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这在 PHP 7 中更容易:
只需使用
$salt = random_bytes($numberOfDesiredBytes);
生成盐。无论如何,你需要盐做什么?如果是密码,只需使用
password_hash()
和password_verify()
。This is easier in PHP 7:
Just use
$salt = random_bytes($numberOfDesiredBytes);
to generate a salt.What do you need a salt for, anyway? If it's for passwords, just use
password_hash()
andpassword_verify()
.您可能想查看
mcrypt_create_iv()
。You might want to take a look at the documentation (and comments) for
mcrypt_create_iv()
.您可以使用函数
mycrypt_create_iv()
,从 PHP 版本 5.3 开始,它还使用 Windows 服务器上的随机源(不仅在 Unix 上)。在使用它之前,您应该检查常量MCRYPT_DEV_URANDOM
是否已定义。与随机不同,如果没有足够的可用熵,urandom 不会阻塞服务器。由于密码盐应该是唯一的(不一定是随机的),urandom 对我来说似乎是一个不错的选择。
You can use the function
mycrypt_create_iv()
, since PHP Version 5.3 it also uses the random source on a Windows server (not only on Unix). Before using it, you should check if the constantMCRYPT_DEV_URANDOM
is defined.Unlike random, urandom does not block the server, if there is not enough entropy available. Since the password salt should be unique (not necessarily random), urandom seems to be a good choice to me.
uniqueid
不太适合生成随机字符串,因为它也是基于microtime
的。CPU 周期通常比微时间周期短得多,这可能导致循环内给定变量可能保持不变。
将第二个参数“entropy”设置为 true,
将提供增加的随机性。
为了获得与大多数字符集良好兼容的随机字符串,可以将base64编码应用于mcrypt初始化向量函数
mcrypt_create_iv
:将字符字母减少到2^ 6Bit增加了大小,上面已经说明了。
uniqueid
is not well suited for generating a random string as it too ismicrotime
based.A CPU Cycle is generally much shorter than a microtime-tick, which may lead to possible constancy for a given variable within loops.
Setting the second parameter "entropy" to true,
will provide increased randomness.
To get a random string that is well compatible with most character-sets,one may apply base64 encoding to the mcrypt initilization vector function
mcrypt_create_iv
:Reducing the character-alphabet to 2^6Bit increases the size, which is accounted for above.
从
/dev/urandom
读取,或使用openssl_random_pseudo_bytes()
。Read from
/dev/urandom
, or useopenssl_random_pseudo_bytes()
.看起来这个问题有一个公认的答案,但我只是想在经过一些研究和阅读这篇文章后额外声明,如果你不把所有鸡蛋放在一个篮子里,你可能会增加一些安全性。
我可能建议不要仅仅依赖 PHP 来创建盐并对密码进行哈希处理。如果让数据库完成部分工作,您可以进一步混淆您的解决方案。
有人建议只使用password_hash()和password_verify()。虽然这些都是很好的方法,但我强烈建议坚持除这些方法之外还加入盐的想法。
为了回答这个问题,盐可以是任何真正随机的东西,并且对用户来说是唯一的。只要遵守这两条规则,从技术上讲,您可以随心所欲地生成它。
一些很好的资源:
https://www. codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right
https://auth0.com /blog/将盐添加到散列-存储密码的更好方式/
Looks like this question has an accepted answer but I just want to additionally state after a bit of research and reading this thread that you might add some security if you don't put all your eggs in one basket.
I might suggest not relying solely on PHP to create your salts and hashing your passwords. You can obfuscate your solution a little more if you let the database do part of the work.
Someone suggested just using password_hash() and password_verify(). While those are great methods, I strongly recommend sticking to the idea of incorporating a salt in addition to these.
To answer the question, a salt can be anything that is truly random and enforced as unique to the user. You can technically generate it however you wish as long as you adhere to those 2 rules.
a couple of good resources:
https://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right
https://auth0.com/blog/adding-salt-to-hashing-a-better-way-to-store-passwords/
uniqid() 应该可以满足此目的。
uniqid() should be fine for this purpose.
我认为
microtime()
就足够了。奇怪的是,但我仍然对这个答案投反对票。
尽管我得到的唯一解释是微时间是可以预测的。
这对我来说听起来很奇怪,因为盐总是被认为是公开已知的 - 所以,预测根本没有用处。
I think
microtime()
is enough.Strangely, but I am still getting downvotes for this answer.
Though the only explanation I get is that microtime is predictable.
It sounds strange to me as salt always assumed as openly known - so, there is no use for prediction at all.