有没有办法在没有彩虹表的情况下颠倒散列?

可能重复:
md5解码。 他们怎么做?

这个页面表明像md5()和sha1()这样的散列算法可以被颠倒过来,因为我们现在拥有巨大的处理能力。 在这一点上,我认为只有彩虹表才有可能。 我错了吗?

如果彩虹桌是唯一的出路,那么人们如何能够将用盐做的散列翻转?


那么这个问题总的来说就是这个问题的重复。 但是,要回答您的确切问题:

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

从技术上讲,是的,你错了。 给定足够的处理能力,散列函数不可恢复。 关键在于它需要多少处理能力,在大多数情况下,处理能力远远超出您的想象。 原因是在散列周期的每个阶段,可能值的数量呈指数增长。 对于MD5,每个阶段(其中有64个)会将可能性的数量乘以10 ^ 77(很多零)。 因此,要成功地扭转了MD5,你不得不尝试真正大量可能的排列(背的包络的计算显示了10 ^ 4932尝试量级上的某个地方)。 有了今天创造的最快的超级计算机(每秒大约8 petaflops,或8x10 ^ 15个浮点运算),你可以看到大约10 ^ 4908 年的时间来扭转它。 顺便说一句,现在是宇宙年龄的2.5x10 ^ 4898倍。 真的,这是一个巨大的数字,超出了我们理解人类的能力......

这是绝对最好的情况。

所以在技术上可以扭转。 但实际上,并非如此。

如果彩虹桌是唯一的出路,那么人们如何能够将用盐做的散列翻转?

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

找到这种冲突的最简单方法是预先计算散列列表(通常称为彩虹表)。 基本上所有你需要做的就是在表格中查找散列,看看原件是否在那里。 如果是这样,你就完成了(很简单)。

通常添加盐以对抗彩虹桌。 这是因为如果用户输入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个标准算法可以做到这一点(当然,使用原则)。

    最好的是Blowfish哈希(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);
    }
    

    注意:

    这些都不会保护用户免受非常弱的密码的侵害。 如果他们输入词典单词或通用密码,攻击者可能会破解它。 然而,他们会加强对中等强度密码的防守。

    更多阅读:

  • 许多哈希迭代,每次追加盐?
  • 哈希和加密之间的基本差异
  • MD5解码,他们是如何做到的
  • 彩虹桌死了
  • 您的密码存储不正确
  • 密码存储,盐vs多个哈希

  • 彩虹表“仅仅”是一个预先计算的散列值的大表,有些技巧只存储表的一小部分,仍然能够查找所有值。 在精细的细节,彩虹表其可“翻转” N个可能值(即存在N个散列输出用于该表将产生一个对应的输入)需要一定的时间约1.7 * N来构建-因此构建表实际上比 “只是”尝试N个输入并查看是否匹配给定的散列输出。 表优势是当您有多个希望找到匹配输入的散列输出时。


    也许你可以使用下面的攻击,采用,用来制作散列的技术是一个简单的计算。

    例如,如果使用100中的模块散列进行计算,则我们有:

    输入示例:8379547378输出哈希值:78

    散列值78的通用公式将是78 + 100 * k(k个整数)。 因此,可以尝试所有可能的序列。 请注意,这样可以将搜索空间从100%减少到1%,在这种情况下,模块100可以确定这个数字是10位数的预感,我们可以将搜索范围进一步缩小到78 + 100 k(10 ^ 7 <= k <10 ^ 8)。

    另一种方法是用一些非常棒的哈希和入口填充数据库,然后在这个数据库中搜索。

    我希望我能有所帮助。

    链接地址: http://www.djcxy.com/p/28927.html

    上一篇: is there a way to reverse a hash without rainbow tables?

    下一篇: Is this a good hashing password function in PHP? If not, why not?