我一直想知道的一个概念是使用加密哈希函数和值。我知道这些函数可以生成一个唯一且几乎不可能反转的哈希值,但这是我一直想知道的:
如果在我的服务器上,我在PHP中生成:
md5("stackoverflow.com") = "d0cc85b26f2ceb8714b978e07def4f6e"
当您通过MD5函数运行相同的字符串时,您在PHP安装上获得相同的结果。正在使用一个过程从一些起始值产生一些值。
这是不是意味着有一些方法来解构正在发生的事情并扭转哈希值?
这些函数是什么使得结果字符串无法回溯?
答案 0 :(得分:195)
输入材料可以是无限长度,其输出始终为128位长。这意味着无限数量的输入字符串将生成相同的输出。
如果您选择一个随机数并将其除以2但只记下余数,则分别得到0或1 - 偶数或奇数。是否可以取0或1并获得原始数字?
答案 1 :(得分:49)
如果MD5等散列函数是可逆的,那么它将成为数据压缩算法历史上的一个分水岭事件!很容易看出,如果MD5是可逆的,那么任意大小的任意数据块都可以用128位表示,而不会丢失任何信息。因此,无论原始消息的大小如何,您都能够从128位数重建原始消息。
答案 2 :(得分:27)
与此处最受欢迎的答案强调的相反,加密哈希函数的非注入性(即,有几个字符串散列到相同的值)由大的差异引起(可能无限)输入大小和固定输出大小不是重点 - 实际上,我们更喜欢那些碰撞尽可能少的哈希函数。
考虑这个函数(用PHP表示法作为问题):
function simple_hash($input) {
return bin2hex(substr(str_pad($input, 16), 0, 16));
}
如果字符串太短,则会附加一些空格,然后获取字符串的前16个字节,然后将其编码为十六进制。它具有与MD5散列相同的输出大小(32个十六进制字符,如果我们省略bin2hex部分,则为16个字节)。
print simple_hash("stackoverflow.com");
这将输出:
737461636b6f766572666c6f772e636f6d
此函数也具有与Cody对MD5的答案所突出显示的相同的非注入属性:我们可以传入任何大小的字符串(只要它们适合我们的计算机),并且它将仅输出32个十六进制数字。当然它不能是单射的。
但是在这种情况下,找到一个映射到相同哈希的字符串是很简单的(只需在哈希上应用hex2bin
,就可以了)。如果您的原始字符串长度为16(如我们的示例所示),您甚至会获得此原始字符串。即使你知道输入的长度非常短(除了通过尝试所有可能的输入,直到找到匹配的输入,例如蛮力攻击),MD5的任何类型都不应该是这样的。
加密哈希函数的重要假设是:
显然,我的simple_hash
功能既不符合这些条件。 (实际上,如果我们将输入空间限制为“16字节字符串”,那么我的函数就变得是单射的,因此甚至可以证明第二次前映像抗性和抗冲突性。)
现在存在针对MD5的冲突攻击(例如,有可能产生一对字符串,即使具有相同的前缀,具有相同的散列,但有相当多的工作,但并非不可能有多少工作),所以你不应该不要将MD5用于任何关键的事情。 目前还没有原始攻击,但攻击会更好。
回答实际问题:
这些功能是什么呢? 结果字符串无法回溯?
MD5(以及Merkle-Damgard构造的其他哈希函数)有效地做的是应用加密算法,将消息作为密钥,将一些固定值作为“纯文本”,使用生成的密文作为哈希。 (在此之前,输入被填充并分成块,每个块用于加密前一个块的输出,与其输入进行异或,以防止反向计算。)
现代加密算法(包括散列函数中使用的算法)的制作方式很难恢复密钥,即使是明文和密文(或者即使对手选择其中一个)也是如此。 它们通常通过以每个输出位由每个密钥位(几次)以及每个输入位确定的方式进行大量的位混洗操作来完成此操作。这样,如果您知道完整的密钥以及输入或输出,您只能轻松地回溯内部发生的事情。
对于类似MD5的哈希函数和preimage攻击(使用单块散列字符串,为了简化操作),您只能输入和输出加密函数,而不是密钥(这就是您要查找的内容)对)。
答案 3 :(得分:17)
Cody Brocious的答案是对的。严格地说,您不能“反转”散列函数,因为许多字符串都映射到相同的散列。但是,请注意,要么找到一个字符串,该字符串将映射到给定的哈希值,要么找到两个字符串,这些字符串将映射到相同的哈希值(即 collision < / em>),将成为密码分析师的重大突破。这两个问题的最大困难是良好的哈希函数在密码学中有用的原因。
答案 4 :(得分:12)
MD5不会创建唯一的哈希值; MD5的目标是快速生成一个值,该值根据对源的微小变化而显着变化。
,例如,
"hello" -> "1ab53"
"Hello" -> "993LB"
"ZR#!RELSIEKF" -> "1ab53"
(显然这不是实际的MD5加密)
大多数哈希(如果不是全部)也是非唯一的;相反,它们是唯一足够的,所以碰撞是非常不可能的,但仍然可能。
答案 5 :(得分:8)
考虑哈希算法的一个好方法是考虑在Photoshop中调整图像大小...假设你有一个5000x5000像素的图像,然后你将它的大小调整为32x32。你所拥有的仍然是原始图像的一种表现形式,但它要小得多,并且有效地“抛弃”图像数据的某些部分,使其适合较小的尺寸。因此,如果您要将32x32图像重新调整为5000x5000,那么您所得到的就是模糊不清。然而,因为32x32图像不是那么大,理论上可以想象另一个图像可以缩小尺寸以产生完全相同的像素!
这只是一个类比,但它有助于理解哈希正在做什么。
答案 6 :(得分:4)
哈希冲突比你想象的要可能得多。看一下birthday paradox,以便更好地理解为什么会这样。
答案 7 :(得分:4)
由于可能的输入文件数量大于128位输出的数量,因此不可能为每种可能的输入文件唯一分配MD5哈希值。
加密哈希函数用于检查数据完整性或数字签名(为了效率而签名的哈希)。因此,更改原始文档应表示原始哈希与更改的文档不匹配。
有时使用这些标准:
选择这些标准使得难以找到与给定散列匹配的文档,否则可以通过将原始替换为与散列匹配的文档来伪造文档。 (即使更换是胡言乱语,仅仅更换原件可能会导致中断。)
数字3表示数字2。
至于MD5,它已被证明是有缺陷的: How to break MD5 and other hash functions
答案 8 :(得分:2)
但这是彩虹表发挥作用的地方。 基本上只是大量的值被散列,然后将结果保存到磁盘。然后反转位“只是”在一个非常大的表中进行查找。
显然,这仅适用于所有可能输入值的子集,但如果您知道输入值的边界,则可以计算它。
答案 9 :(得分:2)
中国科学家发现了一种称为“选择前缀冲突”的方式,可以在两个不同的字符串之间产生冲突。
以下是一个示例:http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip
源代码:http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5_source.zip
答案 10 :(得分:1)
正如大多数人已经说过,MD5是为可变长度数据流而设计的,这些数据流被散列为固定长度的数据块,因此许多输入数据流共享一个散列。
但是,如果您确实需要从校验和中找出原始数据,例如,如果您有密码的哈希值并需要查找原始密码,那么谷歌(或您喜欢的任何搜索者)通常会更快)答案的哈希比蛮力。我已经使用这种方法成功找到了一些密码。
答案 11 :(得分:0)
根据定义Hash(加密哈希)函数:不应该是可逆的;不应该有冲突(最不可能)。
回答你的问题:这是单向散列。输入(与长度无关)将生成固定大小的输出(它将基于算法(MD5的512位边界)填充)。信息被压缩(丢失),实际上不可能从反向变换中生成。
关于MD5的其他信息:它容易受到冲突的影响。最近经历了这篇文章, http://www.win.tue.nl/hashclash/Nostradamus/
打开加密哈希实现的源代码(MD5和SHA)可以在Mozilla代码中找到。 (freebl图书馆)。
答案 12 :(得分:0)
现在,为所有可能的字符串预先计算MD5哈希值或任何其他哈希值并存储以便于访问。虽然理论上MD5不可逆,但使用这样的数据库,您可能会发现哪个文本产生了特定的哈希值。
例如,在http://gdataonline.com/seekhash.php尝试以下哈希码,找出我用来计算哈希值的文本
aea23489ce3aa9b6406ebb28e0cda430
答案 13 :(得分:0)
f(x)= 1是不可逆转的。散列函数不是不可逆转的。
这实际上是 必需的 ,以便他们完成确定某人是否拥有散列数据的未损坏副本的功能。这会使蛮力攻击变得极为敏感,这些攻击目前非常强大,尤其是对抗MD5。
在这里和其他地方,有数学知识但很少有密文知识的人也会感到困惑。几个密码只是简单地用密钥流对数据进行异或,所以你可以说密文对应于那个长度的所有明文,因为你可以使用任何密钥流。
然而,这忽略了种子password
产生的合理明文比种子Wsg5Nm^bkI4EgxUOhpAjTmTjO0F!VkWvysS6EEMsIJiTZcvsh@WI$IH$TYqiWvK!%&Ue&nk55ak%BX%9!NnG%32ftud%YkBO$U6o
产生的明显更可能,以至于任何人声称第二种是可能性的被嘲笑。
同样地,如果您尝试在两个潜在密码password
和Wsg5Nm^bkI4EgxUO
之间做出决定,那么就像一些数学家会让您相信的那样难以做到。
答案 14 :(得分:0)
了解所有投票最多的答案意味着什么的最好方法是实际尝试恢复MD5算法。我记得几年前我试图恢复 MD5crypt 算法,而不是恢复原始消息,因为它显然是不可能的,而只是生成一条消息,它会产生与原始哈希相同的哈希值。至少在理论上,这将为我提供一种方法来登录到存储用户的Linux设备:使用生成的消息(密码)而不是使用原始消息(密码)在/ etc / passwd文件中使用密码。由于两个消息都具有相同的结果散列,因此系统会将我的密码(从原始散列生成)识别为有效。那根本不起作用。几周之后,如果我没记错的话,在最初的消息中使用 salt 会杀了我。我不仅要生成一个有效的初始消息,而且还要生成一个盐渍的有效初始消息,这是我永远无法做到的。但是我从这个实验中得到的知识很不错。
答案 15 :(得分:-5)
我喜欢各种各样的论点。 很明显,散列值的真正价值在于为密码等字符串提供人类难以理解的占位符。 它没有特定的增强安全性优势。 假设攻击者获得了使用散列密码的表的访问权限,他/她可以:
在这种情况下,弱密码不能仅仅通过哈希来保护。