在 PHP 中生成盐

发布于 2024-08-26 16:06:02 字数 283 浏览 4 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

最美不过初阳 2024-09-02 16:06:02

这在 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() and password_verify().

忆离笙 2024-09-02 16:06:02

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

您可能想查看 mcrypt_create_iv()

Note: mcrypt has been deprecated in PHP 7.1. Skip to the up-to-date answer.

You might want to take a look at the documentation (and comments) for mcrypt_create_iv().

梦中楼上月下 2024-09-02 16:06:02

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

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

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);

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

Note: mcrypt has been deprecated in PHP 7.1. Skip to the up-to-date answer.

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 constant MCRYPT_DEV_URANDOM is defined.

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);

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.

冷情妓 2024-09-02 16:06:02

uniqueid 不太适合生成随机字符串,因为它也是基于 microtime 的。
CPU 周期通常比微时间周期短得多,这可能导致循环内给定变量可能保持不变。
将第二个参数“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增加了大小,上面已经说明了。

uniqueid is not well suited for generating a random string as it too is microtime 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,

 uniqid('', 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:

$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

Reducing the character-alphabet to 2^6Bit increases the size, which is accounted for above.

半山落雨半山空 2024-09-02 16:06:02

/dev/urandom 读取,或使用 openssl_random_pseudo_bytes()

Read from /dev/urandom, or use openssl_random_pseudo_bytes().

最舍不得你 2024-09-02 16:06:02

看起来这个问题有一个公认的答案,但我只是想在经过一些研究和阅读这篇文章后额外声明,如果你不把所有鸡蛋放在一个篮子里,你可能会增加一些安全性。

我可能建议不要仅仅依赖 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/

毁梦 2024-09-02 16:06:02

uniqid() 应该可以满足此目的。

uniqid() should be fine for this purpose.

执着的年纪 2024-09-02 16:06:02

我认为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文