0

这些天来,每个人都在抨击 MD5 在存储密码方面的问题。但是,如果我只想为可能会使用一次的东西添加一层身份验证,那又如何呢?

这只是一个假设的例子,但假设我有一个允许用户重置密码的功能。我通过电子邮件向用户发送一个链接,他们可以单击该链接来设置新的(随机生成的)密码。

我目前的想法是,我将使用私有盐值和几个标识变量生成一个 MD5 哈希,并使用它来创建链接。

假设此功能的盐是“8b769a378411b705”(我对所有重置密码请求使用相同的盐)。其他识别数据是已经生成的密码散列的用户 ID 和数据库 ID。

salt = "8b769a378411b705" (private)
user_id = 123
pw_id = 456
code = md5(salt + " " + user_id + " " + pw_id)

变成

code = "692a71cd7da194145be209e40fcd3e92"

示例链接:confirm_reset_password.php?user_id=123&pw_id=456&code=692a71cd7da194145be209e40fcd3e92

鉴于 MD5 的问题,这被认为是安全的吗?我应该考虑使用另一种单向哈希,例如 SHA-1?

我一直在使用带有 SHA1 的 PBKDF2 来存储密码,我知道它的部分好处在于它的“慢”以及生成哈希需要多长时间。我可以为这样的目的生成那些更高质量的哈希,但我认为它会适得其反,因为你可以通过用(不正确的)请求轰炸服务器来轻松地让服务器瘫痪,因为每个请求都会导致大量的 CPU 工作产生哈希(特别是因为我使用了很多迭代)。似乎拥有“快速”算法对于单次使用目的是有好处的,但我想知道 MD5 是否仍然是最佳选择。

谢谢!

4

2 回答 2

5

首先,MD5 被认为是不安全的,原因有很多,首先,md5 的彩虹表现在非常庞大,可能覆盖了大部分哈希空间。其次,已知的攻击允许您创建哈希冲突(以产生相同 md5 输出的方式伪装其他数据)。第三,它的 128 位,今天它很短。

现在回到您的问题,如果您没有托管任何对安全至关重要的应用程序,您不存储任何私人数据、医疗数据或任何其他“国家法律控制”的数据,那么您就可以使用 md5。进入你的算法,它不是不安全的,但它也不是超级安全的,它是你的选择。您唯一应该添加的是新鲜度,即某种时间戳,告诉您消息的有效期。其次,您的算法不提供重放保护:),如果用户将使用此链接一次并将其留在浏览器中,攻击者可能会再次使用此链接来重置此密码。这是一个相当严重的缺陷。所以你可能想要修复它。

但我想告诉你一些其他的事情。如果不是绝对必要,请勿使用 CRYPTO!我卑微的请求。您的密码重置方案可以在没有加密和重放保护的情况下轻松实施,并且安全性更高。您需要做的就是向您的表“pw_reset_hash”和“reset_validity”添加额外的列,并用随机数和有效日期填充它们。给用户一个随机数,用完后清空字段,事先检查有效性。瞧 :) 因为它是随机的,它可能比任何散列算法更安全。但是使用安全的 PRNG。

于 2012-12-07T07:09:55.670 回答
2

为什么将密码链接建立在某些东西上?这只会使它的安全性降低(因为它基于一些可能泄漏的已知数据)!在这种情况下,随机生成的代码要好得多。

于 2012-12-07T09:00:19.880 回答