可能的重复项:
MD5 解码。他们是怎么做到的?
本页建议像MD5((和SHA1((这样的哈希算法可以逆转,因为我们现在拥有巨大的处理能力。在这一点上,我认为只有彩虹表才有可能。我错了吗?
万一彩虹表是唯一的出路,那么有人怎么能逆转用盐做的哈希?
嗯,这个问题总体上是这个问题的重复。 但是,要回答您的确切问题:
在这一点上,我认为只有彩虹表才有可能。我错了吗?
从技术上讲,是的,你错了。 只要有足够的处理能力,任何哈希函数都是不可恢复的。 关键点是它需要多少处理能力,在大多数情况下,这比你想象的要大得多。 原因是在哈希周期的每个阶段,可能值的数量呈指数级增长。 对于MD5,每个阶段(有64个(将可能性的数量乘以10^77(很多零(。 因此,要成功反转MD5,您必须尝试大量可能的排列(包络粗计算显示大约10^4932次尝试(。 使用当今最快的超级计算机(大约 8 petaflops,或每秒 8x10^15 次浮点运算(,您大约需要 10^4908 年才能逆转它。 顺便说一下,这是现在宇宙年龄的2.5x10^4898倍。 真的,这是一个巨大的数字,超出了我们人类的理解能力......
这绝对是最好的情况。
因此,从技术上讲,可以逆转。 但实际上,不,事实并非如此。
万一彩虹表是唯一的出路,那么有人怎么能逆转用盐做的哈希?
问题是没有人需要扭转它。 他们只需要找到碰撞。 基本上,碰撞是导致相同输出的两个输入。 因此,如果hash(a) = x
和hash(b) = x
,a
和b
是彼此的碰撞。因此,我们需要做的就是找到一个碰撞(信不信由你比找到确切的输入更容易,因为从技术上讲,有无限数量的输入可以提供特定的输出(。 输入密码的大小,通常冲突是原始密码。
查找此冲突的最简单方法是使用预先计算的哈希列表(通常称为彩虹表(。 基本上,您需要做的就是在表中查找哈希值,以查看原始哈希值是否存在。 如果是这样,你就完成了(这么简单(。
盐通常被添加到对抗彩虹表。 这是因为如果用户输入1234
作为密码,而您使用abcdefghijklmnop
作为盐,则原始密码将被1234abcdefgjhijklmnop
,这明显不太可能出现在彩虹表中。 因此,添加强盐将防止预先计算的彩虹表。
暴力破解
但是,如果您只是做hash(pass + salt)
,则存在一个重大问题。 它不容易受到预先计算的彩虹表的影响,但容易受到暴力强制的影响。 原因是加密哈希函数(如sha1,md5,sha256等(被设计为快速。 他们的传统角色是签名,因此他们需要快速才能发挥作用。 但是,在密码存储中,这是弱点。 使用现代 GPU,攻击者可以在几个小时内暴力破解(只需尝试所有可能的密码排列(一个简单的带有盐的哈希(有关更多详细信息,请参阅我关于它的博客文章(......
最好的预防
最好的预防有两个特点:
-
预先计算值表(彩虹表(并不容易
-
散列单个值并不快(不容易暴力破解(。
事实证明,有一种使用哈希函数的简单方法可以做到这一点。 只需迭代它并使输出依赖于大量哈希函数:
var result = password + salt;
for (var i = 0; i < 10000000; i++) {
result = hash(result + salt);
}
关键是,通过人为地使其变慢并使用盐,您可以使其抵抗预计算和暴力强迫。
事实证明,有 2 种标准算法可以做到这一点(好吧,使用这些原理(。
最好的是河豚哈希(bcrypt(,它并没有真正使用哈希原语函数,而是使用河豚密码的密钥派生周期。 它可以通过 crypt()
在 PHP 中使用。 要使用它:
$hash = crypt($password, '$2a$07$' . $salt . '$');
并验证它
$hash == crypt($password, $hash);
另一种方法(稍微不太优选(是PBKDF2。 要用 PHP 编程:
function pbkdf2($hashFunc, $password, $salt, $iterations, $length = 32) {
$size = strlen(hash($hashFunc, '', true));
$len = ceil($length / $size);
$result = '';
for ($i = 1; $i <= $len; $i++) {
$tmp = hash_hmac($hashFunc, $salt . pack('N', $i), $password, true);
$res = $tmp;
for ($j = 1; $j < $iterations; $j++) {
$tmp = hash_hmac($hashFunc, $tmp, $password, true);
$res ^= $tmp;
}
$result .= $res;
}
return substr($result, 0, $length);
}
注意:
这些都不能保护用户免受非常弱的密码的侵害。 如果他们输入字典单词或通用密码,攻击者仍然有可能破解它。 但是,它们将增加对中等强度密码的防御......
更多阅读:
- 多次哈希迭代,每次都附加盐?
- 散列和加密之间的基本区别
- MD5解码,他们是如何做到的
- 彩虹表死了
- 您存储的密码不正确
- 密码存储,盐与多个哈希
虹表"只是"一个预先计算的哈希值的大表,有一些技巧来存储表的一小部分,并且仍然能够查找所有值。在细节上,一个可以"反转"N个可能值的彩虹表(即有N个哈希输出,表将产生相应的输入(需要大约1.7 * N的时间来构建 - 因此构建表实际上比"只是"尝试N个输入并查看是否与给定的哈希输出匹配要慢。表的优势在于,当您有多个哈希输出,并且要为其查找匹配的输入时。
也许你可以使用以下攻击,采用,用于制作哈希的技术是一个简单的计算。
例如,如果使用 100 中的模块化哈希进行计算,我们有:
示例输入:8379547378输出哈希:78
哈希值 78 的一般公式是 78 +100*k(k 属于整数(。因此,人们可以尝试所有可能的序列。注意,在这种情况下,这将搜索空间从100%减少到模块100的1%。如果有可能确定这个数字是 10 位数字的预感,我们可以将搜索进一步减少到 78 +100 k (10^7<=k<10^8(。
另一种方法是用许多非常棒的哈希值及其入口填充数据库,然后在此数据库中搜索。
我希望我能帮到一点忙。
首先,一般来说,不可能"反转"加密哈希函数。这是因为这些函数通常接受的输入数据远远多于输出的数据。
例如,MD5 需要 512 个输入位(64 字节(并产生 128 位输出(16 字节(。因此,输入中根本没有足够的信息来重建输出。事实上,大约有 2^384(一个非常大的数字(具有完全相同的输出哈希的不同输入。
相反,密码学家谈论了三种不同类型的哈希攻击:
- 第一次原像攻击:给定一个哈希 h,找到任何消息 m,使得哈希 (m( = h
- 第二次原像攻击:给定一个固定的消息 M1,找到任何其他消息 M2,使得 hash(m1( = hash(m2(
- 碰撞攻击:找到任意两条消息 M1 和 M2,使得 hash(m1( = hash(m2(
现在回到这个"逆转"业务。当你想"破解MD5密码"时,你真正想做的是第一次原像攻击:找到任何"密码"m,使得hash(m(与存储的hash h匹配。通常,这将需要通过蛮力进行 2^128 次猜测(比地球上所有计算机在一个世纪内所能管理的还要多(。MD5 中存在已知的弱点,将其降低到 ~2^123,这仍然太难而不实用。
但是由于密码通常是字母和数字的短字符串,因此人们实际可能使用的密码远远少于 2^128 个。还有更多的是 2^40(即大约一万亿(。这仍然很多,但不是那么多,如果你有一年左右或很多 PS3 就不可能全部尝试。但是,如果您知道要破解大量密码怎么办?与其每次进行 2^40 次猜测,您可以将所有可能的密码的哈希存储在磁盘上以备将来使用。这就是(或多或少(彩虹表:有人已经完成了所有工作,因此您只需查找答案并跳过大部分工作。
你是对的,使用盐可以打破这一点。现在你又回到了 2^40 次猜测和一屋子的 PS3。使用更好的哈希函数(如SHA512或SKEIN(并不能真正改变这一点,因为它不会改变您需要尝试的可能密码数量。教训:您需要使用一个很难猜到的密码!
好的,但是MD5和SHA1不仍然被认为是坏的吗?是的,但在这里(还(不是真正重要的方式。这一领域令人兴奋的消息都是关于碰撞攻击的,这与破解SSL安全和数字签名的部分内容有关,但与破解存储的密码无关。密码学家预计这项工作很快就会导致更好的攻击,因此在新程序中使用 MD5 或 SHA1 可能不是一个好主意,但使用 MD5/SHA1 + 适当加盐进行密码存储的程序仍然没问题。
从技术上讲,任何标准的哈希算法都是不可逆的! 因此,一旦您获得了消息的哈希值,就没有办法将原始消息从其哈希字符串中取出。人们试图破解它的唯一方法是使用蛮力攻击。暴力破解是你能做的最愚蠢的事情,尝试所有可能的键!这就解释了为什么安全加密算法的特征之一是具有较大的密钥空间。 但是,如果您在某些情况下使用该过程,它可以是实用的,这就是彩虹表的作用。
彩虹表是预先计算的表,用于所有可能的组合,最大可达一定长度。这意味着您可以创建所有可能的字符(大写和小写(、数字和特殊字符的组合,直到一定长度。据我所知,最完整的彩虹表可以打破最多 10 个字符的字符串哈希,其中包括数字、大写和特殊字符,所以如果你的字符串比这长,不应该有任何安全问题打破哈希本身。正如您在此处看到的,可以将Vista密码破坏至8个字符的表的大小超过100GB,并且该数字呈指数级增长,这使得不可能进一步超过10或12个字符。
只要你的字符串不容易猜到,足够长,并且包含大写字母、数字和特殊字符,就不用担心:)
该页面所谈论的暴力破解基本上是动态生成彩虹表。