Cryptography 单向散列函数是如何工作的?(编辑)

Cryptography 单向散列函数是如何工作的?(编辑),cryptography,md5,cryptographic-hash-function,Cryptography,Md5,Cryptographic Hash Function,我读了维基百科关于md5哈希的文章,但我仍然不明白哈希如何不能“重组”回原始文本 有人能向对密码学知之甚少的人解释一下这是如何工作的吗?函数的哪个部分是单向的?考虑一个真正基本的散列-对于输入字符串,返回每个字符的ASCII值之和 hash( 'abc' ) = ascii('a')+ascii('b')+ascii('c') = 97 + 98 + 99 = 294 现在,给定散列值294,您能告诉我原始字符串是什么吗?显然不是,因为“

我读了维基百科关于md5哈希的文章,但我仍然不明白哈希如何不能“重组”回原始文本


有人能向对密码学知之甚少的人解释一下这是如何工作的吗?函数的哪个部分是单向的?

考虑一个真正基本的散列-对于输入字符串,返回每个字符的ASCII值之和

hash( 'abc' ) = ascii('a')+ascii('b')+ascii('c')
              = 97 + 98 + 99
              = 294
现在,给定散列值294,您能告诉我原始字符串是什么吗?显然不是,因为“abc”和“cba”(以及无数其他)给出了相同的散列值

加密哈希函数的工作方式相同,只是算法显然要复杂得多。总是会有冲突,但如果您知道字符串
s
散列到
h
,那么构建另一个也散列到
h
的字符串应该是非常困难的(“计算不可行的”),因为散列是一种(非常)有损编码

为了给你一个简单的例子,想象一个虚构的5个字母的单词的2个字母编码,称为X编码。X编码的算法很简单:取单词的首字母和末字母

所以

显然,您无法从其编码SE(假设我们可能的输入范围都是5个字母的单词)重构SAUCE。这个词也可以简单地用空格来表示


另一方面,SAUCE和SPACE都产生SE作为编码,这一事实被称为冲突,您可以看到X-ecoding不会产生很好的散列。:)

因为到目前为止,每个人都简单地定义了什么是哈希函数,所以我要咬一口

单向函数不仅仅是一个散列函数——一个丢失信息的函数——而是一个函数
f
,对于它,给定一个图像
y
(“SE”或现有答案中的294),很难找到一个前图像x,使得
f(x)=y

这就是为什么它们被称为单向的原因:你可以计算一个图像,但是你找不到给定图像的预图像

到目前为止,现有答案中提出的普通哈希函数都不具有此属性。它们都不是单向加密哈希函数。例如,给定“SE”,您可以很容易地提取输入“SXXXE”,这是一个具有X-encode(“SXXXE”)=SE属性的输入

没有“简单”的单向函数。他们必须很好地混合他们的输入,这样不仅你根本无法识别输出中的输入,,而且你也无法识别另一个输入

SHA-1和MD5曾经是流行的单向函数,但它们几乎都已崩溃(专家知道如何为给定的图像创建预图像,或者几乎能够这样做)。有一个竞赛正在进行,以选择一个新的标准之一,这将被命名为

反转单向函数的一个明显方法是计算多个图像,并将它们保存在一个表中,该表将每个图像与生成它的前图像相关联。为了在实践中实现这一点,所有单向函数都有一个大的输出,至少64位,但可能要大得多(比如说,512位)

编辑:大多数加密哈希函数是如何工作的

通常,它们的核心是一个函数,该函数对一个位块(a)进行复杂的转换。该函数应该几乎是双射的(它不应该将太多的序列映射到同一个图像,因为这会在以后造成弱点),但它不必完全是双射的。这个函数迭代了固定的次数,足以使输入(或任何可能的输入)无法识别


以SHA-3环境中的一个强有力的候选者为例。它的核心功能是迭代72次。函数的创建者知道如何有时将输出与某些输入关联起来的迭代次数只有25次。他们说它的“安全系数”为2.9。

这里有一个非常简单的例子。假设我是一名初级密码学家,我创建了一个哈希函数,该函数执行以下操作:

int SimpleHash(file) {
    return 0 if file.length is even;
    return 1 if file.length is odd;
}
现在是测试
SimpleHash(specialFile)
为0我的原始文件是什么?


显然,没有办法知道(尽管您可能很容易发现我的哈希是基于文件长度的)。无法基于哈希“重建”我的文件,因为哈希并不包含我的文件所做的一切。

简单来说,哈希函数的工作原理是将输入数据弄得一团糟

例如,见。它通过512位块处理输入数据。每个块被分成16个32位字。共有64个步骤,每个步骤使用16个输入字中的一个。因此,在算法过程中,每个单词被使用四次。这就是单向性的来源:任何输入位在多个位置输入,在两个这样的输入之间,函数将所有当前数据混合在一起,以便每个输入位影响128位运行状态的大部分。这可以防止您通过只查看部分数据来反转函数或计算冲突。您必须查看整个128位,128位块的空间太宽,无法有效地遍历

现在MD5在这方面做得并不好,因为可以找到该函数的冲突。从密码学家的角度来看,MD5是一个旋转加密函数。一个消息块M(512位)的处理使用输入状态V(128位值)并计算新状态V'as V'=V+E(M,V),其中'+'是逐字加法,“E”恰好是对称加密函数(也称为“块密码”),它使用M作为密钥,V作为要加密的消息。仔细看,E can是一种“扩展的Feistel网络”,类似于DES分组密码,具有四分之一而不是两半。细节在这里并不重要;我的观点是,在使用该结构的散列函数(称为“Merkle Damgård”)中,构成“好”散列函数的因素与构成块ci的因素类似
int SimpleHash(file) {
    return 0 if file.length is even;
    return 1 if file.length is odd;
}
4 + 3 = 7  
7 - 3 = 4  
4 * 5 = 20  
20 / 4 = 5
22 % 7 = 1  
1  ?  7 = 22  
1  ?  22 = 7