使用MD5加密即使更加困难也更安全了。

6

可能是重复问题:
PHP密码的安全哈希和盐

我看到有人像这样编写密码哈希:

md5(uniqid(mt_rand('password', 15), true));

这是一种安全的方法吗?它是否有效?


8
一旦密码被哈希了,他们如何验证密码?此外,mt_rand 的参数应该是整数而非字符串。 - gen_Eric
1
啊,@Rocket,这是什么问题?!!! - Engineer
我个人使用phpass - gen_Eric
@itsme 这就是你开始做错的地方。你没有启用错误报告。 - PeeHaa
请查看http://crackstation.net/hashing-security.htm,您可能会发现它非常有趣。 - Diego Agulló
3个回答

11

这并不是一种安全的方式。它是可破解的,而且在你的例子中,它是不可重复的。你必须将随机值与哈希本身一起存储。如果数据库被攻击,那么暴力破解哈希就变得极为简单。

你应该知道MD5和SHA1是PHP中可用的最弱哈希算法之一。

更好的方法是使用 crypt() 函数,并选择 CRYPT_BLOWFISHPBKDF2

更新

另外,正如PeeHaa提到的那样,它不起作用。 mt_rand('password', 15) 将导致 Warning: mt_rand() expects parameter 1 to be long, string given on line X


@PeeHaa,是的,因为它不可重复。 - tereško

6
不仅不安全,而且根本无法正常工作。 mt_rand需要两个参数,一个是最小值,另一个是最大值。
mt_rand('password', 15)

这将把'password'转换为整数(0),然后返回015之间的随机数。
uniqid(mt_rand('password', 15), true)

这将生成一个唯一的ID,并在其前面加上上一步骤的随机数,计算出类似于以下内容的结果:
144ffb22886d58e1.82100749

接着对该字符串进行 MD5 哈希。

很明显,这段代码是毫无用处的。原始密码被转换为0并被永久丢失,因此你只是在哈希随机数,这是毫无意义的。现在你已经得到了哈希值,就没有办法再次验证它了。由于密码被转换,所以用户输入什么都不重要。

因此,不,这段代码不安全,请勿使用。

我个人使用 phpass 库。它是安全的,而且使用起来很简单。


假设我像这样不使用 mt_rand()md5(uniqid('passwrd', true));,这是更好的选择吗? - itsme
@itsme:问题在于:以后如何验证密码?您需要能够稍后生成相同的哈希值,而使用uniqid无法实现。uniqid不适用于密码,它用于生成唯一ID(如UUID)。 - gen_Eric
1
为什么是-1?这个答案有什么问题吗? - gen_Eric
1
我有同样的问题,我的问题出了什么问题?但我没有投反对票,我通常会投赞成票。 - itsme

2
坦白说,我不会使用MD5作为存储密码的哈希算法。我会考虑使用像bcrypt这样的东西。此外,我甚至不知道你的例子如何工作,但无论如何,如果你想要保护它,请远离MD5,至少要避免SHA1,并从其他人的错误中吸取教训并使用盐。

我认为如果你使用一个好的盐,md5可以是安全的,但我同意新的算法是未来的发展方向。 - gen_Eric
1
@Rocket 如果你只是用md5()来为密码加盐,那么它并不安全。 - PeeHaa
MD5在性能方面已经进行了超级优化,因此在某些情况下仍然可以使用暴力破解方法,但对于安全的密码哈希实现,我仍不建议使用MD5。 - sean
1
@Rocket:你的正确理由是错误的。在输入未知的密码用途中,md5 没有被破解。目前针对 md5 的所有攻击都需要了解原始输入才能利用。但是,你是错误的,因为即使使用 sha512,也没有安全的 hash(pass + salt)。问题在于哈希太快。看看 这个答案。使用高成本衍生算法(如 PBKDF2 或 BCrypt)。 - ircmaxell
@ircmaxell:啊,我明白了。看起来md5是为了速度而构建的,而不是为了安全性。我对安全/密码学不太了解,所以我猜我不知道我在说什么。感谢提供那个链接。 - gen_Eric
sha512 也是为了速度而构建的。对于数字签名(哈希的正常用例),速度至关重要。您需要能够快速安全地验证大型文档。因此,md5 被设计为既具有速度又具有安全性(因为所有哈希都是如此)。只是 md5 在正常用例下被破解了... - ircmaxell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接