散列(MD5,SHA1,SHA256,SHA384,SHA512) - 为什么不能从散列中获取值?

时间:2012-01-13 12:38:10

标签: c# .net security hash cryptography

On this blog post,有一句话如下:

  

此哈希对于给定文本是唯一的。如果使用哈希函数   再次在同一文本上,你会得到相同的哈希。但是没有办法   从哈希中获取给定的文本。

原谅我对数学的无知,但我无法理解为什么不可能从哈希中获取给定的文本。

我会理解,如果我们使用一个密钥加密该值而另一个密钥解密,但我无法在脑海中弄明白。幕后真的发生了什么?

任何让我清醒的事情都会受到赞赏。

8 个答案:

答案 0 :(得分:6)

哈希不是加密。

哈希产生“摘要” - 输入的摘要。无论输入大小如何,散列大小始终相同(请参阅MD5如何为任何输入大小返回相同大小的结果)。

使用哈希,您可以从几个不同的输入(哈希冲突)中获取相同的哈希 - 您将如何反转这个?哪个正确的输入?

我建议在此问题上阅读this blog post from Troy Hunt,以便更好地了解哈希,密码和安全性。

加密是另一回事 - 您将从输入和密钥中获得不同的密码 - 并且随着输入的增大,密码的大小将趋向于更大。如果您有正确的密钥,则可逆


更新(遵循不同的评论):

虽然可能会发生冲突,但是当使用加密重要的哈希(就像你发布的那些哈希)时,它们将是罕见且难以产生的。

当散列密码时,总是使用salt - 这会减少哈希被rainbow tables反转几乎为零的几率(假设已使用了好的盐)

您需要决定散列成本(可能是处理器密集型)和您要保护的成本之间的权衡。

由于您只是保护登录详细信息,因此使用.NET成员资格提供程序应提供足够的安全性。

答案 1 :(得分:3)

散列函数是多对一的函数。这意味着许多输入将给出相同的结果,但对于任何给定的输入,您只能获得一个结果。

为什么会出现这种情况可以直观地看待一个哈希函数,它接受任意长度的字符串输入并生成一个32位整数。显然,字符串远远超过2 ^ 32,这意味着您的散列函数不能为每个输入字符串提供唯一的输出。 (有关更多讨论,请参阅http://en.wikipedia.org/wiki/Pigeonhole_principle - “使用和应用程序”部分专门讨论哈希)

鉴于我们现在知道哈希函数的任何结果都可以从一个或多个输入生成,除了结果之外我们没有任何信息,我们无法确定使用哪个输入,因此无法逆转。

答案 2 :(得分:2)

至少有两个原因:

  1. 哈希通常使用非对称函数进行计算 - 这意味着找到某些操作的反向值比在直接操作中更难(在时间/资源/努力方面)。

  2. 相同算法的哈希值始终具有相同的长度 - 这意味着可能存在一组有限的哈希值。这意味着对于每个哈希都会有无限个冲突 - 不同的源数据块形成相同的哈希值。

答案 3 :(得分:1)

它不是加密/解密。例如,简单的哈希函数:

int hash(int data)
{
    return data % 2;
}

问题?

答案 4 :(得分:0)

散列就像使用校验和来验证数据,而不是加密或压缩数据。

答案 5 :(得分:0)

这基本上是数学,Hash函数是一个非1到1的函数。它在所有二进制数据B *的集合中取一个输入范围,并将其映射到固定长度的固定长度二进制字符串集Bn左右。(这个定义是在上面) 您可以尝试通过强力计算给定散列的前映像,但不知道大小,它是无限的。

答案 6 :(得分:0)

您可以散列所需的任何数据长度,从单个字节到TB级文件。所有可能的数据都可以散列为256位值(以SHA-256为例)。这意味着从SHA-256哈希算法输出有2 ^ 256个可能的值。但是,可以输入SHA-256的可能值超过2 ^ 256个。您可以输入任何所需长度的字节组合。

由于输入可能比可能的输出多得多,因此一些输入必须生成相同的输出。由于您不知道输出中产生了多少可能的输入,因此无法可靠地倒退。

答案 7 :(得分:0)

一个非常简单的哈希算法是获取文本中每个单词的第一个字符。如果你使用相同的文本,你总是可以得到相同的哈希值,但不可能只从每个单词的第一个字符重建原始文本。

上面我的回答中的示例哈希:

AvshawbtttfcoewwatIyttstycagotshbisitrtotfohtfcoew

现在尝试从给定的哈希中找出相应的文本。 ; - )