md5 哈希使用密码作为盐?
md5($password.md5($password))
这对于密码散列来说足够好吗?我并不是要求将其与 bcrypt 之类的东西进行比较。
如果不安全,请告诉我原因。
md5($password.md5($password))
is this good enough for password hashing? I am not asking for comparing this to something like bcrypt.
if it is not secure, tell me why.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
为每个用户的密码使用不同的盐的原因是,攻击者无法获取所有散列密码的列表,并查看其中是否有任何一个与“密码”或“12345”等简单内容的散列相匹配。如果您使用密码本身作为盐,那么攻击者可以计算
md5("12345".md5("12345"))
并查看它是否与任何条目匹配。据我了解,您可以在密码表上使用四个级别的散列:
有关更多详细信息,请查看编码恐怖帖子“您可能错误地存储了密码”。
The reason to use a different salt for each user's password is so that an attacker can't take a list of all the hashed passwords and see if any of them match the hash of something easy like "password" or "12345". If you were to use the password itself as salt, then an attacker could calculate
md5("12345".md5("12345"))
and see if it matched any entries.As I understand it, there are four levels of hashing you can use on a password table:
For more details, check out the Coding Horror post, "You're probably storing passwords incorrectly".
虽然这对我来说似乎已经足够了,但如果有人基于相同的算法预先计算了彩虹表(这是很有可能的),那么它将面临危险。
所以,我宁愿使用电子邮件来获取盐,这看起来非常安全但可用。偏执狂可能会添加一些恒定的全站盐。
人们经常对密码盐(理论上)过于重视,而在他们的应用程序中,他们允许简单的密码,并在实践中通过不安全的 HTTP 以纯文本形式传输它们。
每一天我都会看到有关盐或哈希的问题。
并且没有一个关于密码复杂性的问题。而
您唯一关心的应该是密码复杂性。
为什么?让我告诉你。
极好的盐+弱密码=几秒钟内即可破解
总是假设攻击者知道盐。因此,通过使用一些最常用密码的字典并向其中添加[任何超随机超长]盐,可以在几秒钟内发现弱密码。暴力破解短密码也是如此。
合理的盐 + 强密码 = 牢不可破 相当
独特的盐使预先计算的表毫无用处,而好的密码则使字典和暴力攻击毫无用处。
Although it seems quite enough to me, it will be in danger in case if someone precomputed a rainbow table based on the same algorithm (what is quite possible).
So, I'd rather use an email for the salt which seems pretty secure yet usable. Paranoids may add some constant site-wide salt.
People often makes too big deal out of password salt (in theory), while in their applications they allow simple passwords and transfer them in plain text over insecure HTTP in practice.
Every freakin' day I see questions regarding salt or hash.
And not a single one regarding password complexity. While
The only your concern should be password complexity.
Why? Let me show you.
extraordinary good salt + weak password = breakable in seconds
It is always assumed that salt is known to attacker. So, by using some dictionary of most used passwords and adding [whatever extra-random-super-long] salt to them, a weak password can be discovered in seconds. Same goes for brute-forcing short passwords.
just sensible salt + strong password = unbreakable
Quite unique salt makes precomputed tables useless and good password makes both dictionary and brute-force attacks good for nothing.
它对字典攻击没有多大作用,计算字典的难度只是单个
md5
的两倍,而且现在md5
相当便宜。It doesn't do much against dictionary attacks, only twice as hard to compute a dictionary versus a single
md5
, andmd5
is pretty cheap these days.MD5 本身并不安全,因为它被部分破坏(冲突)并且摘要太小。如果您不想使用 bcrypt、scrypt 或 PBKDF2 等正确的密码派生函数,您可以新设计至少应使用 SHA-256(并计划在 SHA-3 推出时迁移到 SHA-3,因此请务必存储用于散列密码的方案和结果,以便这两种方案可以共存当人们更改密码时,您将使用新的哈希过程)。
如果您打算以任何身份使用 MD5 来销售您的程序,则可能会成为大多数政府销售的障碍(例如,在美国,使用的算法必须经过 FIPS 140-2 批准,许多其他国家/地区也有相同的要求)。
MD5 is not secure in itself because it is partially broken (collisions) and is too small of a digest anyway. If one doesn't want to use a proper password derivation function à la bcrypt, scrypt or PBKDF2 you should at least use SHA-256 for new designs (and have a plan to migrate to SHA-3 when it will be out, so be sure to store the scheme you used to hash the password with the result, so both scheme can coexist as you use the new hashing procedure when people change passwords).
If you intend to sell your program using MD5 in any capacity can be a show stopper for most government sales (e.g. in the US algorithms used must be FIPS 140-2 approved and many other countries got the same kind of requirements).
建议使用随机密码盐对密码进行哈希处理,以便知道密码哈希的攻击者无法将其与
如果您使用密码作为盐,攻击者可以首先从他们的字典中预先计算 $word.md5($word) 的哈希值
The reason why random password salt is recommended for hashing password, so that an attacker who knows the password hash can't compare it to rainbow table of pre-calculated hashed from dictionary.
If you're using password as salt, attacker can pre-calculate hashes of $word.md5($word) first from their dictionary
通过您的解决方案,您几乎无法实现使用盐来对抗预先计算的字典攻击的目的。
对于预先计算的字典,顾名思义,有人已经提前为特定单词创建了一个哈希表(计算的
md5
结果)。考虑这个表
hashtable
(带有虚构的哈希值,仅用于说明目的)针对您的表测试这些值可能很简单:
通过匹配,您就拥有了密码。
但是,如果您没有对密码进行哈希处理,那么在将其与密码再次连接并再次进行哈希处理之前,使用预先计算的字典来攻击它会更加困难。因为这样的话,如果预计算表只考虑了单词的单个实例,那么密码将是例如
md5( 'testtest' )
,这使得预计算表毫无价值。您可以很容易地看到,如果您不使用密码作为盐,而是使用另一个随机字符串作为盐,事情会变得更加困难。当您为每个密码创建唯一的盐时,事情会变得更加困难。当然,如果您为每个密码创建唯一的盐,则必须将盐与数据库行中的密码一起保存在单独的列中。
所以我的建议是:
或者实际上,根本不使用
md5
,而是使用更好的sha1
、sha256
(或更高版本)哈希算法。With your solution you pretty much defeats the purpose of using a salt against precomputed dictionary attacks.
With a precomputed dictionary, as the name implies, someone has already created a table of hashes (the computed
md5
result) for particular words, ahead of time.Consider this table
hashtable
(with imaginary hashes, just for illustration purposes)Testing these values against your table, could be as simple as:
With a match, you'ld have the password.
However, if you did NOT hash the password, before concatenating it again with the password and hashing it once more, it would be more difficult to attack it with a pre-computed dictionary. Because then the password would be for instance
md5( 'testtest' )
which makes the precomputed table worthless, if the precomputed table has only taken into account single instances of the word.You can easily see that it gets even more difficult if you did not use the password as a salt, but used another random string as salt. And it gets even more difficult still, when you create unique salts for every passwords. Of course, if you create unique salts per password, you'd have to save the salt in a separate column along with the passwords in a database row.
So my advice would be:
Or actually, don't use
md5
at all, but use the far bettersha1
,sha256
(or higher) hashing algorithms.