最近,我一直在尝试在我在Internet上偶然发现的脚本的日志上实现自己的安全性。在尝试学习如何制作自己的脚本以为每个用户生成盐的努力之后,我偶然发现了 password_hash
。
据我了解(根据此页面),盐为)当您使用 password_hash
时,已经在行中生成。这是真的吗?
我遇到的另一个问题是,吃2盐不是很明智吗?一个直接在文件中,一个在DB中?这样一来,如果有人在DB中妥协了盐,您仍然直接在文件中有盐?我在这里读到,储存盐从来都不是一个明智的主意,但是它总是使我感到困惑。
Recently I have been trying to implement my own security on a log in script I stumbled upon on the internet. After struggling of trying to learn how to make my own script to generate a salt for each user, I stumbled upon password_hash
.
From what I understand (based off of the reading on this page), salt is already generated in the row when you use password_hash
. Is this true?
Another question I had was, wouldn't it be smart to have 2 salts? One directly in the file and one in the DB? That way, if someone compromises your salt in the DB, you still have the one directly in the file? I read on here that storing salts is never a smart idea, but it always confused me what people meant by that.
发布评论
评论(5)
使用
password_hash
是存储密码的推荐方法。不要将它们与DB和文件分开。假设我们有以下输入:
您首先执行此操作:
然后查看输出:
如您所见。 (我认为您采取了这些步骤)。
现在,您将此哈希密码存储在数据库中,确保您的密码列足够大,可以保持Hashed值(至少60个字符或更长的时间)。当用户要求将它们登录时,您可以通过此操作来检查数据库中的密码输入:
官方参考
Using
password_hash
is the recommended way to store passwords. Don't separate them to DB and files.Let's say we have the following input:
You first hash the password by doing this:
Then see the output:
As you can see it's hashed. (I assume you did those steps).
Now you store this hashed password in your database, ensuring your password column is large enough to hold the hashed value (at least 60 characters or longer). When a user asks to log them in, you check the password input with this hash value in the database, by doing this:
Official Reference
是的,您正确理解了它,功能password_hash()将单独生成盐,并将其包含在结果的哈希值中。将盐存储在数据库中是绝对正确的,即使知道,它也可以完成工作。
您提到的第二种盐(存储在文件中的盐)实际上是胡椒或服务器端钥匙。如果在哈希之前添加(如盐),则加入胡椒粉。但是,有一种更好的方法,您可以首先计算哈希,然后使用服务器端密钥加密(双向)哈希。这使您有可能在必要时更改密钥。
与盐相反,该钥匙应保密。人们经常将其混合并尝试隐藏盐,但是最好让盐完成工作并用钥匙添加秘密。
Yes you understood it correctly, the function password_hash() will generate a salt on its own, and includes it in the resulting hash-value. Storing the salt in the database is absolutely correct, it does its job even if known.
The second salt you mentioned (the one stored in a file), is actually a pepper or a server side key. If you add it before hashing (like the salt), then you add a pepper. There is a better way though, you could first calculate the hash, and afterwards encrypt (two-way) the hash with a server-side key. This gives you the possibility to change the key when necessary.
In contrast to the salt, this key should be kept secret. People often mix it up and try to hide the salt, but it is better to let the salt do its job and add the secret with a key.
在PHP密码功能中内置的后向后兼容性明显缺乏讨论。值得注意的是:
crypt()
,并且本质上是与crypt()
-format哈希,即使它们使用过时和/或不安全的哈希算法。例如:
输出:
作为最终注意,鉴于您只能在登录时重新限制用户的密码,您应该考虑“日落”不安全的遗产哈希以保护您的用户。我的意思是,在经过一定的宽限期之后,您删除了所有不安全的[例如:裸露的md5/sha/否则弱],并使您的用户依靠应用程序的密码重置机制。
There is a distinct lack of discussion on backwards and forwards compatibility that is built in to PHP's password functions. Notably:
crypt()
, and are inherently backwards-compatible withcrypt()
-format hashes, even if they use obsolete and/or insecure hash algorithms.password_needs_rehash()
and a bit of logic into your authentication workflow can keep you your hashes up to date with current and future algorithms with potentially zero future changes to the workflow. Note: Any string that does not match the specified algorithm will be flagged for needing a rehash, including non-crypt-compatible hashes.Eg:
Output:
As a final note, given that you can only re-hash a user's password on login you should consider "sunsetting" insecure legacy hashes to protect your users. By this I mean that after a certain grace period you remove all insecure [eg: bare MD5/SHA/otherwise weak] hashes and have your users rely on your application's password reset mechanisms.
是的,是的。您为什么怀疑该功能的PHP常见问题解答? :)
运行
password_hash()
的结果有四个部分:,因此,散布是其中的一部分。
当然,您可以为增加的安全层加入额外的盐,但老实说,这在常规的PHP应用程序中是过分的。默认的BCrypt算法很好,可选的吹鱼可以说更好。
Yes, it's true. Why do you doubt the php faq on the function? :)
The result of running
password_hash()
has has four parts:So as you can see, the hash is a part of it.
Sure, you could have an additional salt for an added layer of security, but I honestly think that's overkill in a regular php application. The default bcrypt algorithm is good, and the optional blowfish one is arguably even better.
要使数据库密码在数据库黑客攻击时更安全,您可以使用电子邮件地址和密码创建多个列(我认为还应在我的看法中编码电子邮件地址),例如:从email_1到email_7的列以及password_1的列到密码_7。密码可以存储在一个电子邮件列之一和电子邮件地址之一中。在其余六个中,我们可以存储一个加密的随机字符串字符串。其次,当哈希时,我们可以使用各种哈希功能,例如我们的密码$密码,
我们在数据库中存储
$ hash_db
。哈希长度为128个字符,看起来像是使用SHA512算法。To make the database password more secure in the event of a database hack, you can create several columns with the email address and password (the email address should also be encoded in my opinion), e.g.: columns from email_1 to email_7 and columns from password_1 to password_7. The password can be stored in one of the email columns and the email address in one of the password columns. In the remaining six we can store an encrypted random string of characters. Secondly, when hashing, we can use various hashing functions, e.g. our password $password,
We store
$hash_db
in the database. The hash is 128 characters long, it looks like the sha512 algorithm is used.