在Java中追加文件时更新校验和(MD5、SHA1)。

4

在我们追加文件时,是否可以根据散列值更新校验和(MD5、SHA1)。

  1. 我已经上传了文件A到服务器,并且我已经有了包含MD5散列值的MD5文件。
  2. 我想将一个新的数据块(byte [])添加到文件A中,并且必须更新Md5文件的新哈希值。

在不必读取整个文件A创建文件哈希的情况下,是否可以更新新文件的MD5哈希值(因为如果文件A太大,它将花费太多时间)。


1
为什么不将新数据存储为不同的文件? - Scary Wombat
3个回答

3

如果且仅如果,你可以选择新的数据块由一个0x80字节、取决于文件A大小的一定数量的0x00字节和4个包含文件A位长度的字节组成,然后是任何其他你想要的数据,那么是的。

这被称为长度扩展攻击,它是所有使用Merkle-Damgard结构的哈希函数的密码学弱点,其中包括MD5 SHA1和SHA-2家族,但不包括SHA-3家族。这不是真正的编程问题,更适合在crypto.SX上讨论,在那里已经有很多关于它的问题,例如https://crypto.stackexchange.com/questions/17733/sha1-multipart-calculationhttps://crypto.stackexchange.com/questions/3978/understanding-the-length-extension-attack

然而,如果您在数据末尾之前保存哈希通常的内部状态,并从那里恢复并继续“更新”,添加(不受限制的)新数据,就像其他答案更多或少地意味着的那样,您可以计算新哈希(如果您想要重复此过程,则还可以计算新保存的状态)。如何访问此状态以及它需要表示的确切方式取决于您使用的实现。您标记了Java,尽管您实际的问题没有提到它;使用Java提供的加密(JCA)来完成这个任务将非常困难,因为JCA故意隐藏所有支持算法的细节,背后是一系列简化的、抽象的门面类。另一方面,如果您重新编码这些哈希,访问内部状态可能会相当容易。如果您使用BouncyCastle的“轻量级”实现,则可能不是很难,尽管可能存在他们改变实现的风险,但我必须详细查看。存储和检索可能是一个问题,也可能不是。

2
据我从维基百科关于MD5SHA1的文章所看到的,这应该是可能的。您需要将旧哈希拆分回内部状态变量(应该只是一些位移),然后继续计算新哈希。免责声明:我自己没有尝试过,只是阅读了有关算法的维基页面。
无论如何:MD5和SHA1已经被破解了。请使用更新的sha2或sha3哈希。

我尝试过了,但没有成功,但你是对的,原理是正确的。 - deFreitas

0

我认为您需要重新阅读整个文件。

MD5(如果我没记错)的工作原理是通过维护一些内部“寄存器”来完成的,每消耗一个字节算法就会改变这些寄存器的状态。因此,从先前的MD5计算继续的唯一方法是在先前的结束点处以某种方式存储了这些寄存器的状态。

看一下MD5计算的内部情况-如果找不到Java版本的话,我认为JavaScript中有一些例子可以说明一般原则。即使编写良好,它也有点丑陋(我想这就是重点所在)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接