哈希应该多长时间才能绝对安全?

信息安全 密码学 哈希
2021-09-03 19:29:49

是否有某种规则来确定散列应该有多大以确保消息的安全性(意味着一条消息恰好映射到给定的散列)?可以应用于任何消息的东西,例如 32 位数字或 8 个字母的 ASCII 密码。

4个回答

恰好一条消息映射到给定的哈希

由于鸽巢原理,这是不可能的。只要散列函数的输入消息可以大于散列本身,就可以保证某些消息相互碰撞并映射到同一个散列。这是正常的,对哈希本身的安全性来说不是问题。

您只需要确保散列函数足够大,以至于故意发现此类碰撞(碰撞攻击)在计算上是不可行的。n位的哈希摘要具有n / 2位的抗冲突性为了实现 128 位的安全性以防止碰撞攻击,因此需要一个 256 位的散列摘要。当然,这是假设哈希是加密安全的(如 SHA-256),以避免出现走捷径的攻击,并且比暴力破解更容易找到冲突。

这在很大程度上取决于您想要实现的目标。首先,正如森林已经指出的那样,你真正想要的只有一个输入映射一个哈希 - 在一般情况下 - 是不可能的。如果散列与输入一样长或更长,则在特殊情况下是可能的。由于您提到了 32 位整数,因此确实存在 32 位整数到整数哈希。
但是请注意,可能的输入数量在 32 位时是如此之小,以至于构建查找表实际上是非常可行的(仅占用 32GB,因此在我现在使用的计算机上,查找表将完全适合 RAM !)。不用说,无论您使用什么实际算法,这都不安全,也不可能是安全的。

如果您打算用哈希识别某些东西(例如文件或字符串),并且恶意篡改不是考虑因素或至少不是您的首要任务,那么您几乎可以考虑 64 位“足够好”和 128 位“绝对安全”。
CRC32 甚至不提供加密安全哈希所提供的保证,多年来一直被认为是“非常好”,可以区分事物并可靠地识别意外修改(与 32 位相比,64 位是完全不同的数量级!! !)。UUID是 128 位的,当它们显然不是时,它们被认为是“唯一的”。但对于所有实际问题,它们都是.
我打算添加 GIT,它用于托管 Linux 内核和其他用于数十亿设备的安全相关软件(因此使其成为一个非常有趣的攻击目标)使用 128 位散列来将东西分开并且安全,但它实际上是 160 位...

现在,如果担心恶意篡改,您可能需要一个安全的散列算法(因此 CRC 无法解决问题),但您不一定需要更多位。这仅取决于您要保护什么,保护多长时间以及针对哪种攻击。
Siphash 或 Cityhash(默认情况下,在原始/通用配置中,也有 32 位和 128 位变体)只有 64 位。如果您使用它来确保您通过 Internet 发送的一些合理大小的消息的完整性,这非常好,并且绝对安全。足够强大的攻击者能否在 15-20 分钟内发现碰撞?当然。但谁在乎呢,15 分钟后,14 分 59 秒就太迟了,他无法用它做点什么。
另一方面,如果您打算将它用于存储更长时间的东西,那就不好了。

在这种情况下,您需要至少128 位,更好的 160 位,并且为了以合理的确定性说“绝对安全”,您将需要 256 位或更高,这又取决于您到底想要什么。AES-CGM,被认为“对几乎每个人都足够好”,最多有 128 位(低至 96)。

您的攻击者是否可以选择两个输入,因此生日攻击是否适用?在这种情况下,128 位仅值 64 位(或者,如果投影成立,量子计算机上的 42 位)。这肯定有点微不足道,不足以说“足够好”,更不用说“绝对安全”了。

您是否担心第二次原像攻击,即您要选择其中一个输入?在这种情况下,128 位将“非常好”,160 位将“牢不可破”,而 256 位将“荒谬地牢不可破”。除非算法本身被破坏,否则就是这样。

tl;dr
总而言之,如果您更喜欢不需要考虑先决条件的无条件答案,则应考虑该答案为256 或更多
256 位在“非常不可能”的范围内,但应该考虑到算法确实会随着时间的推移而被破坏,因此 256 位算法在 10-20 年内可能只值得 2^140 或 2^150 的工作量,那里是没有办法知道的。如果您有点偏执,那可能不足以让您说“绝对安全”(尽管对于大多数人来说,我想这仍然足够了)。

因此,在不知道您的偏执程度的情况下,我说“256 或更多”。一些额外的位并不会真正花费太多,但它们会产生巨大的影响。让它384甚至512,为什么不呢。如果一个 512 位算法被非常非常显着地破坏和削弱到 2^300 的工作量,那么超维外星人发明的超量子超级魔法计算机可以通过应用数学和物理上不可能的魔法,进一步将其减少到 2^150 位的工作量,那么您仍然可以继续使用。

散列函数的输出大小为其安全级别设置了上限。任何加密散列函数都应具有的三个主要属性是抵抗冲突、第一原像和第二原像攻击。

如果算法具有n位安全性,则意味着不存在破坏相关安全属性的攻击,这需要少于 2 n步(大约和平均)才能成功。如果n足够大,那么我们实际上可以确定没有人有足够的计算能力来攻击一个系统。

从具有n位输出的散列函数中,当涉及到原像攻击时,我们可以期望高达n位的安全性,但不会更高可以假设通过蛮力搜索原像并在平均 2 n次尝试后成功。)

然而,对于碰撞阻力,生日问题意味着您需要 2* n位而不是n位。

我们通常以 128 位安全为目标,这意味着可接受的最小摘要大小为 256 位。128 位安全性为您提供了足够大的安全余量,使用较少的输出位可能仍然是安全的,但使用太少的位是有风险的。

注意:这是一个上限。尽管像 Murmur3、CityHash、xxHash 和其他算法可能声称质量很高并且输出很长,但它们并没有提供有意义的安全性。

绝对不要仅根据其输出大小来选择算法。输出大小仅决定哈希的最大理论强度。不是它的实际实力。

而是选择人们认为安全的抗碰撞哈希函数,例如。Blake-2、SHA-3、Skein 或 SHA-2。

注意 2:如果您使用的是 SHA-512 之类的东西,那么您可以将算法视为不同的输入总是会产生唯一的输出。在概率几乎等于 1 的情况下,您不会得到任何真实世界输入集的重复摘要。

看到冲突摘要的实际概率取决于您尝试散列多少消息以及可能有多少输出。您可以尝试散列的不同消息的数量自然是有限的,因为您计算散列的能力是有限的。

散列函数并不是真正的单射函数,但软件开发人员可以使用大型抗冲突散列函数并将其视为真实的。无意中产生一个或多个碰撞的可能性在技术上是非零的,但人的大脑无法理解它是多么难以置信的不可能。

如果我们必须让每个消息摘要恰好对应一条消息,那么我们的摘要必须与可能的最长消息一样大。

我们将消息视为一个巨大的 N 位整数,并使用可逆函数从中计算另一个 N 位整数。一种方法是使用对称密码(然后其密钥指定散列函数)对消息进行加密。

当然,与最长消息一样长的哈希是不切实际的,因为消息摘要的一个关键要求是它们是固定的、小尺寸的,通常比摘要消息本身小得多。

但是,如果出于某种原因您需要将一条小消息转换为没有冲突的代码,并且很难从中恢复该消息,则上述方法将是一种方法。