目前最安全的单向加密算法是什么?

67

众所周知,单向加密是数据库中加密用户密码的一种便捷方式。这样,即使数据库管理员也无法知道用户的密码,只能猜测一个密码,用相同的算法进行加密,然后将结果与数据库中的加密密码进行比较。这意味着找回密码的过程需要大量的猜测和处理能力。

考虑到计算机速度不断提高,数学家们仍在开发这些算法,我想知道哪种算法在现代计算能力和加密技术方面最安全。

我几乎一直使用MD5,想知道是否有更好的选择。我应该考虑使用其他算法吗?

另一个相关问题:对于这样的加密密码,字段通常应有多长?我必须承认,我几乎不了解加密,但我认为MD5哈希(作为示例)可以更长,并且可能需要更多的处理能力来破解。或者,字段长度根本不重要,只要加密密码首先适合其中就行了吗?


32
哈希函数不是加密函数。加密函数有逆函数,可以解密加密的值以获得原始值。但是哈希不能被解密。只有可能找到碰撞(导致相同哈希值的输入值)。 - Gumbo
3
无论输入的位数/字节数/字符串长度如何,任何哈希函数/算法的输出长度始终相同。对于MD5来说,它的输出始终为128位。 - Jared Updike
不用担心字段的长度。在几乎所有情况下,猜测密码并对其进行哈希处理比强制进行碰撞要快得多,并且128位足够大以抵御暴力攻击,直到宇宙热死亡。 - David Thornley
2
要了解哈希函数的最新信息,请查看eHash Wiki,特别是哈希函数动物园http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo。 - outis
7个回答

64
警告:由于此帖子是在2010年编写的,GPU已被广泛用于暴力破解密码哈希。价格适中的GPU每秒可以运行10亿个MD5。这意味着即使是完全随机的8个字符的字母数字密码(62个可能的字符),也可以在6小时内进行暴力破解。SHA-1只稍微慢一点,需要一天时间。您的用户密码要弱得多,并且(即使加盐)每秒钟也会下降数千个密码。哈希函数旨在快速执行。您不想让它处理密码。使用scrypt、bcrypt或PBKDF-2。
MD5在1996年被发现存在漏洞,不应再用于加密目的。SHA-1是常用的替代方案,但存在类似问题SHA-2哈希函数族是SHA-1的当前替代品。SHA-2的成员分别称为SHA-224、SHA-256、SHA-384和SHA-512。

目前,有几个哈希函数正在竞争成为下一个标准化的密码哈希算法 SHA-3。将在2012年选择优胜者。现在还不应该使用其中任何一个!

对于密码哈希,您也可以考虑使用类似于 bcrypt 的东西。它被设计得足够缓慢,以使大规模暴力攻击变得不可行。您可以自己调整缓慢程度,因此当计算机变得更快时,它可以变得更慢。

警告: bcrypt基于一种较旧的双向加密算法Blowfish,今天存在更好的替代品。我认为bcrypt的密码哈希属性并没有完全被理解。如果我错了,请有人纠正我;我从未找到过一个可靠的来源,从密码学的角度讨论bcrypt的属性(除了其缓慢性)。

使用MD5对于公钥加密或数字签名而言是一个糟糕的想法,但对于密码哈希而言并不是同样灾难性的。但如果可以选择,只需选择更强的算法。

使用良好的哈希函数并不足以保护您的密码安全。你应该将这些密码与一起哈希,这些盐应该是长的并且具有密码学上随机性。如果可能的话,您还应该帮助用户选择更强的密码或短语。长度总是越长越好。

9
“越长越好”并不一定正确。我听说过有人强制要求用户选择更长的密码,结果导致他们选择熵值更低的密码,以便记住它们。个人而言,如果我每天使用,则可以记住8位字母数字随机生成的密码。比这更长,我将不得不自己编造密码,但我不知道它们的熵值是多少。 - Steve Jessop
1
@Steve 攻击者不会逐渐从低熵密码尝试到更高的密码。他们会尝试字典攻击,然后是暴力破解。因此,“ooGoo!ooooooo876”比“d!NA0sue732bnfuw”具有较低的熵,但它并不会更不安全。 - Lucas
1
@Lucas:无论是“ooGoo!ooooooo876”还是“d!NA0sue732bnfuw”,都没有任何熵的相关意义,因为它们是常量而不是随机变量。严谨地说,我应该说“选择密码作为具有较少熵的随机变量的输出”,而不是“选择具有较少熵的密码”。低熵密码生成方案更有可能生成密码,这些密码会在字典/暴力攻击的早期部分中出现,假设(出于安全考虑)攻击者对密码的选择方式有一定的了解,并且已经合理地设计了他的攻击。 - Steve Jessop
一个更长的密码当然有更多的熵潜力。但是molf说“越长越好”,这是错误的:由8个随机字母数字字符组成的密码比由两个随机词典单词组成的密码更好。如果您为双词密码生成方案引入足够的额外随机性,那么最终它将更好。当被迫选择更长的密码时,用户是否会实际这样做是心理学问题,而不是信息论问题。我对答案的信心不足以强制实施任何除极小长度限制之外的东西。 - Steve Jessop
3
我已经在编辑中加入了一条警告,指出使用GPU可以快速破解MD5、SHA-1等算法,因此这些算法都不再适合用于密码存储。请随意更改/恢复等操作。 - derobert
显示剩余5条评论

10

非常好的问题!这个页面是一篇不错的阅读材料。特别是作者声称MD5不适用于哈希密码:

问题在于MD5很快。它的现代竞争者,如SHA1和SHA256,也是如此。速度是现代安全哈希的设计目标,因为哈希是几乎每个加密系统的构建块,并且通常会按数据包或消息执行。

速度正是您不希望在密码哈希函数中出现的。

文章随后继续解释了一些替代方案,并将Bcrypt推荐为“正确选择”(他的话,不是我的话)。

免责声明:我完全没有尝试过Bcrypt。请将其视为友好的建议,但不是我自己的技术经验所支持的东西。


作者还推荐了为FreeBSD开发的密码哈希方案,它在核心上使用MD5,但迭代哈希函数数千次。glibc中也有一个基于SHA-1的类似结构可用。 - caf

6
为了增强密码强度,您应该使用更多种类的符号。如果您的密码长度为8-10个字符,则变得相当难以破解。尽管增加长度会使其更安全,但仅当您使用数字/字母/其他字符时才会如此。
SHA1是另一种哈希(单向加密)算法,它速度较慢,但具有更长的摘要(编码消息)(160位),而MD5只有128位。
然后,SHA2更加安全,但使用较少。

7
我会注意到在防御暴力破解攻击时,速度慢实际上是一种优势 - Anon.
1
这并不是说它“更慢”,而是“即使使用专用硬件/预计算表/数学分析也难以快速实现...”这一点非常重要。NIST SHA-3竞赛的理论基础是,尽管当前的加密哈希函数在通用计算机上仍然像以前一样慢,但由于各种其他原因,它们最近已经被削弱了。特别是MD5(请参见MD5维基百科页面)。 - Pascal Cuoq
1
你仍然可以使用彩虹表攻击SHA1。我已经将大部分新开发转移到了SHA-256。 - Xorlev
1
@Xorlev 你可以为 任何 哈希算法构建彩虹表。构建彩虹表的实用性取决于可能的输入数量,而不是算法的强度。 - Nick Johnson
1
@Xorlev:但这有什么关系呢?有了64位的盐值,任何人都不可能拥有SHA-1的彩虹表与正确的盐值吗?他们可以在得知要破解的密码的盐值后开始生成它,但这与对SHA-1进行字典攻击没有区别。SHA-1的彩虹表的存在对您没有威胁。SHA-1的预像攻击的存在可能是一个日益增长的威胁。 - Steve Jessop
显示剩余5条评论

4

对密码进行加盐始终是一种额外的防御层。

$salt = 'asfasdfasdf0a8sdflkjasdfapsdufp';
$hashed = md5( $userPassword . $salt );

2
每次设置密码时,生成新的盐(salt)非常重要,而不是固定值。 - caf
@caf: 如果每次计算都是相同的,这是否仍会使计算花费更多时间,从而增加暴力破解所需的时间?- 如果盐值每次都不同,则必须将其存储在与登录机制的密码相同的行中,以便能够将哈希尝试与真实密码进行比较。 - Teekin
如果盐值始终相同,攻击者可以a)并行地暴力破解您的所有密码(每个测试哈希可以与您的所有密码哈希进行比较); b)在查看您的数据库之前预先计算哈希。是的,盐应该与哈希值一起存储 - 这正是UNIX风格的密码哈希所做的。 - caf
1
实际上,虽然最好每次使用不同的盐,但事实证明即使使用固定的盐也是有用的,只要全世界的系统不都使用相同的固定盐。加盐的目的是防止预先计算的表格,例如经常用于破解Windows密码的彩虹表。因此,如果您的盐与其他人的不同,它仍然是有用的。另请参见Wikipedia on salting - Paul
1
不使用盐的主要问题在于,如果10个用户具有完全相同的密码,则这10个用户的$哈希值完全相同。因此,您只是破解了10个帐户(假设您可以看到数据库中的内容)。 - Alexis Wilke

3
鉴于计算机速度不断提高,数学家仍在开发这些算法,RSA加密是安全的,因为它依赖于一个非常大的数字很难被分解。最终,计算机将变得足够快,可以在合理的时间内分解该数字。为了保持领先,您需要使用更大的数字。
然而,对于大多数网站,哈希密码的目的是使具有访问数据库权限的人读取密码变得不方便,而不是提供安全性。出于这个目的,MD5是可以接受的。
这意味着如果恶意用户获得了您的整个数据库的访问权限,他们不需要密码。(前门上的锁无法阻止我从窗户进来。)
注1:仅因为MD5已经“破解”并不意味着您可以随时反转它。

2
然而,对于大多数网站来说,散列密码的目的是为了让那些能够访问数据库的人无法轻易地阅读密码,而不是提供安全保障。这可能是大多数网站实现的全部,但目的应该是使反向获取用户存储的任何密码变得不切实际 - 而这完全是可以实现的。 - Nick Johnson
同意,我已经努力向我的同事们解释为什么MD5的弱点不应该排除其用于密码哈希。不用说,使用盐和最小密码强度仍然是明智的建议。 - MarkR
我同意,如果他们拥有你的整个数据库,他们不需要用户密码就可以进入你的系统,但由于很多人重复使用他们的密码,忽视强哈希算法和盐的重要性仍然是一个坏主意。 - FercoCQ
确实。而且(将近9年后),我认为是时候放弃简单的MD5,以及密码本身了。从谦卑的用户名和密码中仍然可以获得很多效用,但我期待着那一天,生物识别和易于使用的第二因素成为一种实用且安全的身份验证方式。 - Seth

2
除了作为一种具有密码学安全性的单向函数外,用于密码保护的好哈希函数应该难以通过暴力破解 - 即通过设计变慢。其中一个最好的是scrypt。从主页上可以看到:

我们估计,在现代(2009年)硬件上,如果花费5秒钟计算派生密钥,则针对scrypt的硬件暴力攻击成本大约比针对bcrypt(查找相同密码)的类似攻击成本高4000倍,并且比类似攻击PBKDF2的成本高20000倍。

话虽如此,从常用的哈希函数来看,对SHA系列中的任何东西进行数千次迭代都是相当合理的非关键密码保护。

此外,始终添加盐以使其不可能共享努力来同时暴力破解许多哈希。


0

NIST目前正在运行一个竞赛,以选择一种新的哈希算法,就像他们选择AES加密算法一样。因此,这个问题的答案在未来几年可能会有所不同。

您可以查找提交并自行研究它们,看看是否有一种适合您使用的算法。


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