哈希是否包含任何原始文件的数据?

信息安全 哈希
2021-08-12 06:55:56

我不是计算机科学家,但想更多地了解 SHA-256 等哈希。我是否相信哈希只是一个文件产生特定输出(哈希)的声明,并且它不以任何方式包含原始文件的数据?因此,如果有人拥有一个文件的哈希值,那么即使拥有世界上所有的计算能力,他们唯一可以重新创建原始文件的方法就是自己随机重新创建文件,直到他们拥有一个具有相同哈希值的文件?

或者更简单地说:

哈希是唯一计算机文件的唯一序列号。序列号不包含有关文件的任何内容。了解文件的唯一方法是通过反复试验独立地重新创建它,其中哈希只提供确认创建的文件与原始文件匹配的确认。

4个回答

可能包含,也可能不包含。例如,可以将消息的第一个字母作为散列。对于特定目的,它可能是一个好的散列算法,但绝对不是一个好的加密散列。

所以我假设你的问题是关于加密哈希的。

理想的 加密哈希算法(除其他外)具有以下属性:

  • 除非尝试所有可能的消息,否则从其哈希值生成消息是不可行的
  • 对消息的微小更改应该会如此广泛地更改散列值,以致新散列值看起来与旧散列值不相关
  • 找到两个具有相同哈希值的不同消息是不可行的

(在现实世界中,将“不可行”一词替换为“极不可能”。)

因此,这些属性中的第一个表明您的陈述几乎是正确的

了解文件的唯一方法是通过反复试验独立地重新创建它,其中哈希只提供确认创建的文件与原始文件匹配的确认。

因为它存在一些问题:

  • 所有消息的集合是无限的,因此不可能进行穷举搜索

  • 盲目搜索的上下文中,哈希不提供创建文件与原始文件匹配的确认,因为本质上存在许多冲突(不同消息的相同哈希)。

  • 您甚至很难找到具有给定哈希的 1 个文件(消息),因此“试错”方法只会给您错误。

哈希是从任意长度输入到固定长度输出的映射。一个常见的误解是散列函数不应该有冲突(两个输入获得相同散列的情况)。这是错误的。根据鸽巢原理,必须有无限次的碰撞,因为映射是从无限大的输入到固定长度的输出。然而,一个好的散列函数应该很难找到冲突。

可以通过将单个值映射到0和任何其他值映射到来构造错误的哈希1由此,确定0文件原始数据的哈希值a. 这是一个实现:

def bad_hash(x):
    if x == 'a':
        return 0
    return 1

良好的散列旨在确保执行任何反向映射(从散列到将生成散列的输入)在计算上是困难的,并确保散列可以反转为无限量的输入数据(因此即使您找到一个散列到目标的值,其他输入值也会散列到同一目标)。

因此,对于一个好的散列函数(sha-256当然被认为是好的),揭示散列并不能揭示原始数据是什么。

对于sha-256,除了穷举搜索之外,没有其他已知的方法可以找到输入数据,即使找到了,也无法确定那是特定的输入数据。

这是非技术人员的简短答案。

询问是否有好的哈希

MD5("StackExchange") = f25cb1c6953bb0c62c639f3d7a242ec4

包含任何原始数据有点像问,模运算的结果是否包含原始商和除数的任何提示。

1337 % 2 = 1

理论上——如果只给出1的话——对手可能会在你用了很长时间后猜测出你使用13372原始商和除数1如果您在文件和大量数据的背景下考虑这一点,猜测将变得难以克服。这就像用猎枪向空中射击并试图击中特定的空气分子。可能,但真的很难。

在这种情况下,很容易找到另一个给出相同结果的商和除数。但对于普通的散列函数,情况并非如此。

当您发现一个输入创建与第二个相同的哈希时,这称为冲突。例如1337 % 2 = 11339 % 2 = 1就是这样。当使用一个好的散列函数时,几乎不可能找到冲突。如果不是,则认为它在密码学上不安全。这是一个相当复杂的话题,在本网站和Cryptography StackExchange上进行了广泛讨论。典型的最终用户无需担心这一点。[需要引用]

您不能从散列中派生原始数据。

这就像在没有任何其他信息的情况下尝试在给定一些各种原子堆栈的情况下重新创建一个对象。

此外,可以从不同的数据中获得相同的哈希(即使这种情况非常罕见并且很难故意获得——这里的论文),这称为 SHA 冲突(在 SHA 的情况下),它呈现与哈希相关的证明不是 100% 有效。