Everyone is shooting down MD5 these days for its issues in the context of storing passwords. But what about uses where I just want to add a layer of authentication to something that will likely be used once?
This is just a hypothetical example, but let's say I have a feature to allow a user to reset their password. I email the user a link that they can click to set a new (randomly-generated) password.
My current thinking is that I'll generate an MD5 hash, using a private salt value, and a couple of identifying variables, and use that to create the link.
Let's say the salt for this feature is "8b769a378411b705" (I use the same salt for all reset password requests). The other identifying pieces of data are the user ID and a database ID of the already-generated password hashes.
salt = "8b769a378411b705" (private)
user_id = 123
pw_id = 456
code = md5(salt + " " + user_id + " " + pw_id)
Run Code Online (Sandbox Code Playgroud)
which becomes
code = "692a71cd7da194145be209e40fcd3e92"
Run Code Online (Sandbox Code Playgroud)
example link: confirm_reset_password.php?user_id=123&pw_id=456&code=692a71cd7da194145be209e40fcd3e92
Is this considered safe, in light of the issues with MD5? Is there another one-way hash I should consider using, like SHA-1?
I've been using PBKDF2 with SHA1 for storing passwords, and I understand that part of its benefit is in its "slowness" and how long it takes to generate hashes. I could generate those higher-quality hashes for purposes like this, but I think it can backfire, since you could easily bring a server to its knees by bombarding it with (incorrect) requests, since each one results in a significant CPU job to generate the hash (especially since I am using lots of iterations). It seems that having a "fast" algorithm is good for single use purposes, but I'm wondering if MD5 is still the best choice.
Thanks!
首先,由于多种原因,MD5被认为是不安全的;首先,到目前为止,md5的Rainbow表非常庞大,并且可能覆盖了大多数哈希空间。其次,已知的攻击使您可以创建哈希冲突(以将产生相同md5输出的方式伪装其他数据)。它的128位的三分之二,以今天的短。
现在回到您的问题,如果您不托管任何对安全性要求很高的应用程序,则不存储任何私有数据,医疗数据或任何其他“受国家法律控制”的数据,那么使用md5就是您的好选择。进入您的算法,它不是不安全的,但是它也不是超级安全的,这是您的选择。您唯一需要添加的就是新鲜度,即某种时间戳,可以告诉您消息的有效期。其次,您的算法不提供重播保护:),如果用户一次使用此链接并将其留在浏览器中,攻击者可能会再次使用此链接来重置此密码。这是一个非常严重的缺陷。因此,您可能需要修复它。
但是我想告诉你其他事情。如果不是绝对必要,请不要使用加密!我的谦虚要求。您的密码重置方案可以轻松实现,无需加密,并具有重放保护功能,并具有更高的安全性。您需要做的就是在表“ pw_reset_hash”和“ reset_validity”中添加其他列,并用RANDOM编号和有效日期填充它们。向用户发出一个随机数,并在使用后清除字段,请事先检查其有效性。瞧:)因为它是随机的,所以它可能比任何哈希算法都更安全。但是请使用安全的PRNG。