分组密码有一个密钥;密钥的保密性是密码安全性的基础。另一方面,散列函数根本没有密钥,也没有建立散列函数安全性的“秘密数据”。
分组密码是可逆的:如果您知道密钥,就可以解密加密的内容。从技术上讲,对于给定的密钥,分组密码是可能的分组值空间的排列。散列函数是不可逆的,它们不是以任何方式排列的。
分组密码在固定大小的块(AES 为 128 位块)上运行,用于输入和输出。哈希函数具有固定大小的输出,但应接受任意大的输入。
所以分组密码和散列函数真的是不同的动物。与其试图区分它们,不如更容易看出它们的共同点:即知道如何设计分组密码的人也相当擅长设计散列函数,因为分析数学工具是相似的(相当很多线性代数和布尔函数,真的)。
让我们来看看更正式的定义:
分组密码是由密钥选择的一系列排列。对于n的某个固定值,我们考虑n位块的空间B;然后B的大小为2 n。键是来自空间K的值,通常是另一个m位序列的空间( m不一定等于n)。一个键k在2 n中选择一个排列!B的可能排列。
一个分组密码被认为是安全的,只要它在计算上与在2 n中均匀随机选择的排列没有区别!可能的排列。为了对此建模,假设攻击者可以访问两个黑盒,一个使用攻击者不知道的密钥实现分组密码,另一个是真正的随机排列。攻击者的目标是分辨哪个是哪个。他可以让每个盒子加密或解密他想要的任何数据。可能的攻击是尝试所有可能的密钥(有2 m个这样的密钥),只找到一个,它产生与其中一个框相同的值;这平均花费2 m-1 次密码调用。一个安全块密码是一种这样的通用攻击是最好的攻击。
AES 在 128 位块 ( n = 128) 和 128、192 和 256 位密钥上定义。
散列函数是一个单一的、完全定义的、可计算的函数,它将任意长度的位序列作为输入,并输出固定长度r的值(例如,对于 SHA-256, r = 256 位)。没有密钥,没有函数族,只有一个任何人都可以计算的独特函数。
如果满足以下条件,则认为哈希函数h是安全的:
- 找到原像在计算上是不可行的:给定一个r位值x,找到m使得h(m) = x是不可行的。
- 找到第二个原像在计算上是不可行的:给定m,找到与 m不同的m '是不可行的,这样h(m) = h(m')。
- 找到冲突在计算上是不可行的:找到彼此不同的m和m'是不可行的,使得h(m) = h(m')。
有一些通用攻击可以找到原像、第二原像或碰撞,成本分别为2 r、2 r和2 r/2。因此,只有当r足够大以至于2 r/2是非常巨大的成本时,才能达到实际的安全性。在实践中,这意味着r = 128(一个 128 位的哈希函数,例如 MD5)是不够的。
以一种非正式的方式,如果散列函数“看起来”是在接受相同输入的可能函数中随机且一致地选择的,那将是很好的。但这是一个定义不明确的属性,因为我们谈论的是一个独特的函数(概率总是隐含地表示平均值和重复的经验;你不能真正拥有一个函数的概率)。此外,作为一个随机函数与抵抗碰撞和原像并不完全相同。这是关于随机预言机模型的争论。
然而,可以从分组密码中构建散列函数。这就是Merkle-Damgård构造的作用。这需要使用输入消息作为密钥块加密的; 所以分组密码根本没有按原意使用。使用 AES,这证明令人失望:
- 它产生了一个 128 位输出的散列函数,对于 2011 年可用技术的安全性来说太小了。
- 散列函数的安全性依赖于对分组密码没有相关密钥攻击。相关密钥攻击在用于加密时对分组密码没有任何实际意义;因此,AES并不是用来抵御此类攻击,而事实上,AES有一个几个弱点在这方面-而不是用于加密的担心,但一大隐忧,如果AES是在梅克尔- Damgard结构中使用。
- 性能不会很好。
Whirlpool散列函数是一种基于AES启发的分组密码的设计,而不是真正的密码。该分组密码具有大大改进(和更重)的密钥调度,可以抵抗相关密钥攻击并使其可用作散列函数的核心。此外,该分组密码适用于 512 位块,而不是 128 位块。惠而浦被认为是安全的。众所周知,Whirlpool 非常慢,所以没有人使用它。
一些最近的哈希函数设计试图重用AES 的一部分——准确地说,是使用一个内部操作,该操作很好地映射到最近的 Intel 和 AMD 处理器所具有的AES-NI指令上。参见例如ECHO和SHAvite-3;作为SHA-3 竞赛的一部分,这两个功能都获得了相当多的曝光,并且被认为“相当安全”。最近的 Intel 和 AMD 处理器速度非常快。在其他较弱的架构上,如果散列函数性能有一定的机会实际上很重要,那么这些函数非常慢。
还有其他构造可以从块密码中生成散列函数,例如Skein中使用的构造;但它们也往往需要比 AES 所定义的更大的块。
总结:不仅分组密码和散列函数完全不同;但是用 AES 构建散列函数的想法被证明是有问题的。这并不容易,有限的 AES 块大小是主要障碍。