有没有办法在没有彩虹表的情况下反转哈希


is there a way to reverse a hash without rainbow tables?

可能的重复项:
MD5 解码。他们是怎么做到的?

本页建议像MD5((和SHA1((这样的哈希算法可以逆转,因为我们现在拥有巨大的处理能力。在这一点上,我认为只有彩虹表才有可能。我错了吗?

万一彩虹表是唯一的出路,那么有人怎么能逆转用盐做的哈希?

嗯,这个问题总体上是这个问题的重复。 但是,要回答您的确切问题:

在这一点上,我认为只有彩虹表才有可能。我错了吗?

从技术上讲,是的,你错了。 只要有足够的处理能力,任何哈希函数都是不可恢复的。 关键点是它需要多少处理能力,在大多数情况下,这比你想象的要大得多。 原因是在哈希周期的每个阶段,可能值的数量呈指数级增长。 对于MD5,每个阶段(有64个(将可能性的数量乘以10^77(很多零(。 因此,要成功反转MD5,您必须尝试大量可能的排列(包络粗计算显示大约10^4932次尝试(。 使用当今最快的超级计算机(大约 8 petaflops,或每秒 8x10^15 次浮点运算(,您大约需要 10^4908 才能逆转它。 顺便说一下,这是现在宇宙年龄的2.5x10^4898倍。 真的,这是一个巨大的数字,超出了我们人类的理解能力......

这绝对是最好的情况。

因此,从技术上讲,可以逆转。 但实际上,不,事实并非如此。

万一彩虹表是唯一的出路,那么有人怎么能逆转用盐做的哈希?

问题是没有人需要扭转它。 他们只需要找到碰撞。 基本上,碰撞是导致相同输出的两个输入。 因此,如果hash(a) = xhash(b) = xab是彼此的碰撞。因此,我们需要做的就是找到一个碰撞(信不信由你比找到确切的输入更容易,因为从技术上讲,有无限数量的输入可以提供特定的输出(。 输入密码的大小,通常冲突是原始密码。

查找此冲突的最简单方法是使用预先计算的哈希列表(通常称为彩虹表(。 基本上,您需要做的就是在表中查找哈希值,以查看原始哈希值是否存在。 如果是这样,你就完成了(这么简单(。

盐通常被添加到对抗彩虹表。 这是因为如果用户输入1234作为密码,而您使用abcdefghijklmnop作为盐,则原始密码将被1234abcdefgjhijklmnop,这明显不太可能出现在彩虹表中。 因此,添加强盐将防止预先计算的彩虹表。

暴力破解

但是,如果您只是做hash(pass + salt),则存在一个重大问题。 它不容易受到预先计算的彩虹表的影响,但容易受到暴力强制的影响。 原因是加密哈希函数(如sha1,md5,sha256等(被设计为快速。 他们的传统角色是签名,因此他们需要快速才能发挥作用。 但是,在密码存储中,这是弱点。 使用现代 GPU,攻击者可以在几个小时内暴力破解(只需尝试所有可能的密码排列(一个简单的带有盐的哈希(有关更多详细信息,请参阅我关于它的博客文章(......

最好的预防

最好的预防有两个特点:

  1. 预先计算值表(彩虹表(并不容易

  2. 散列单个值并不快(不容易暴力破解(。

事实证明,有一种使用哈希函数的简单方法可以做到这一点。 只需迭代它并使输出依赖于大量哈希函数:

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个字符。

只要你的字符串不容易猜到,足够长,并且包含大写字母、数字和特殊字符,就不用担心:)

该页面所谈论的暴力破解基本上动态生成彩虹表。