this page表明,由于我们现在拥有巨大的处理能力,因此可以颠倒像md5()和sha1()这样的哈希算法。在这一点上,我认为只有彩虹表才有可能。我错了吗?
如果Rainbow Tables是唯一的方法,有人可以如何反转用盐制作的哈希值?
答案 0 :(得分:15)
嗯,这个问题一般是This Question的副本。但是,要回答您的确切问题:
此时我认为只有Rainbow Tables才有可能。我错了吗?
从技术上讲,是的,你错了。在给定足够的处理能力的情况下,没有哈希函数是不可恢复的。关键点在于它需要多少处理能力,在大多数情况下,这比你想象的要大得多。原因是可能值的数量在散列循环的每个阶段以指数方式增加。对于MD5,每个阶段(其中有64个)会将可能性的数量乘以10 ^ 77(很多零)。因此,要成功反转MD5,您必须尝试真正大量可能的排列(包络后计算显示大约10 ^ 4932次尝试的某个位置)。使用当今创建的最快的超级计算机(大约8 petaflops,或每秒8x10 ^ 15浮点运算),您正在查看大约10 ^ 4908 年来反转它。顺便提一下,现在是宇宙年龄的2.5x10 ^ 4898倍。真的,这是一个超出我们人类理解能力的巨大数字......
这是绝对最好的情况。
所以技术上可以逆转。但实际上,不是没有。
如果Rainbow Tables是唯一的方法,有人可以如何反转用盐制作的哈希值?
事情是没有人需要来扭转它。他们只需找到一个碰撞。基本上,碰撞是两个输入,导致相同的输出。因此,如果hash(a) = x
和hash(b) = x
,a
和b
是彼此的冲突。因此,我们需要做的就是找到一个碰撞(相信它或不相信比找到确切的输入更容易,因为技术上有无限数量的输入可以给出特定的输出)。输入密码大小时,通常碰撞是原始密码。
找到此冲突的最简单方法是使用预先计算的哈希列表(通常称为彩虹表)。基本上你需要做的就是在表格中查找哈希,看原文是否存在。如果是这样,你就完成了(很容易)。
通常会添加盐以对抗彩虹表。这是因为如果用户输入1234
作为他们的密码,并且您使用abcdefghijklmnop
作为salt,则原始版本将为1234abcdefgjhijklmnop
,这显然不太可能出现在彩虹表中。因此添加强盐可以防止预先计算的彩虹表。
Brute Forcing
但是,如果您只是hash(pass + salt)
,则会引起严重关注。它不容易受到预先计算的彩虹表的影响,但它很容易受到暴力破坏的影响。原因是加密哈希函数(例如sha1,md5,sha256等)设计得很快。他们的传统角色是Signing,所以他们需要快速有用。但是,在密码存储中,这是一个弱点。使用现代GPU,攻击者可以在几个小时内蛮力(只是尝试每个可能的密码排列)一个简单的哈希哈希(有关详细信息,请参阅我的blog post关于它)...
最佳预防
最佳预防有两个特点:
预先计算一个价值表(彩虹表)并不容易
散列单个值并不快(不易暴力)。
事实证明,使用哈希函数有一种简单的方法。简单地迭代它并使输出依赖于大量的散列函数:
var result = password + salt;
for (var i = 0; i < 10000000; i++) {
result = hash(result + salt);
}
关键是,通过人工减速和使用盐,你可以抵抗预先计算和暴力强迫。
事实证明,有两种标准算法可以做到这一点(好吧,使用原则)。
最好的一个是Blowfish hash(bcrypt),它实际上并不使用哈希原语函数,而是使用Blowfish密码的密钥派生循环。它通过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);
}
注意:强>
这些都不会保护用户免受非常弱密码的侵害。如果他们输入字典单词或通用密码,攻击者仍然可能会破解它。然而,他们会增加对中等强度密码的防御......
更多阅读:
答案 1 :(得分:2)
彩虹表“只是”一个预先计算好的哈希值的大表,有一些技巧只能存储表的一小部分,仍然能够查找所有值。在精细的细节中,彩虹表可以“反转” N 可能的值(即有 N 散列输出,表将产生相应的输入)需要时间<要构建em> 1.7 * N - 因此构建表实际上慢而不是“只是”尝试 N 输入并查看是否与给定的匹配哈希输出。表优势是当您有几个哈希输出时,您希望找到匹配的输入。
答案 2 :(得分:2)
也许你可以使用以下攻击,采用,用于制作哈希的技术是一个简单的计算。
例如,如果使用100中的模块化哈希进行计算,我们有:
示例输入: 8379547378 输出哈希: 78
散列值78的通式将是78 + 100 * k(k属于整数)。因此,人们可以尝试所有可能的序列。请注意,在这种情况下模块100将搜索空间从100%减少到1%。如果可以确定这个数字是10位数的预感,我们可以使搜索进一步减少到78 + 100 k(10 ^ 7&lt; = k&lt; 10 ^ 8)。
另一种方法是使用一些非常棒的哈希值及其入口填充数据库,然后在此数据库中搜索。
我希望我能帮助一点。
答案 3 :(得分:1)
从技术上讲,任何标准的哈希算法都是不可逆的!所以一旦得到消息的哈希值,就没有办法从哈希字符串中获取原始消息。人们试图破解它的唯一方法是使用暴力攻击。蛮力是你能做的最愚蠢的事情,尝试所有可能的钥匙!这就解释了为什么安全加密算法的一个特征是具有大的密钥空间。但是如果你在某些情况下使用这个过程它可能是实用的,那就是彩虹表的确如此。
彩虹表是一个预先计算的表,用于所有可能的组合,直到一定长度。这意味着您可以创建所有可能的字符组合(大写和小写),数字和特殊字符,直到一定长度。据我所知,最完整的彩虹表可以打破最多10个字符的字符串哈希,包括数字,大写和特殊字符,所以如果你的字符串长于这个字符串,那么打破哈希本身不应该有任何安全问题。正如您所看到的here,可以破坏最多8个字符的vista密码的表的大小超过100GB,并且该数字呈指数级增长,这使得10或12个字符无法进一步发展。
只要您的字符串不容易猜测,足够长并且包含大写字母,数字和特殊字符,就不必担心:)
答案 4 :(得分:1)
首先,通常,不可能“反转”加密散列函数。这是因为这些函数通常比输出的输入数据多得多。
例如,MD5需要512个输入位(64字节)并产生128位输出(16字节)。因此,在输入中根本没有足够的信息来重建输出。实际上,将有大约2 ^ 384(真正大数字)的不同输入具有完全相同的输出散列。
相反,密码学家谈论对哈希的三种不同攻击:
现在回到这个“扭转”的业务。当你想“破解MD5密码”时,你真正想做的是第一次原像攻击:找到任何“密码”m,使哈希(m)匹配存储的哈希值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 +正确加密密码存储的程序仍然可以。
答案 5 :(得分:0)
该页面正在讨论的强暴行为基本上是动态生成彩虹表。