不同的方法对多个文件的哈希的安全级别是否不同?



我的任务是从多个文件中计算哈希值。
我也已经知道每个单独文件的哈希值。

有两个方法:

  1. hash(f1 + f2 + f3)
  2. hash(hash(f1) + hash(f2) + hash(f3))

在第二种方法中,由于我知道每个文件的哈希值,因此计算量更少。

这两种方法的安全级别不同吗?
哪一种方法更安全?

我不擅长密码学,所以我不能客观地计算出每种方法的安全级别。

TL,DR: usehash(hash(f1) + hash(f2) + hash(f3))

注意:在这个答案中,+表示连接。它从来不是任何一种数字加法。如果您有数字数据,请在将数据转换为字节字符串后应用我的答案。

hash(f1 + f2 + f3)有一个问题:您可以(例如)将一些数据从f1的末尾移动到f2的开头,这不会改变哈希值。这是否是个问题取决于对文件格式有什么约束(如果有的话)以及文件的使用方式。

通常在系统设计中很难确保这不是一个问题。因此,无论何时组合字符串或文件进行散列,都应该确保组合是明确的。有几种不同的方法可以做到这一点,例如:

  • 使用一些现有的格式来处理字符串或文件的打包。例如zip、asn . 1der等
  • 以不包含特定字节的方式编码每个部分,并使用该字节作为分隔符。例如,用Base64编码每个部分并使用换行符作为分隔符。
  • 定义每个部件的最大长度。在每个部分之前,使用固定宽度编码对长度进行编码。例如,如果部分的最大长度为2^64-1字节,则将(f1, f2, f3)的明确连接编码为:
    • 8字节:length(f1)
    • length(f1)bytes:f1
    • 8字节:length(f2)
  • length(f2)bytes:f2
  • 8字节:length(f3)length(f3)bytes:f3

如果你使用哈希的哈希,你就不会遇到这个问题,因为在这里你对你要连接的字符串有一个非常强的约束:它们有一个定义良好的长度(不管哈希算法的长度是多少)。

获取哈希的哈希不会降低安全性。这是一种著名技术的一部分:哈希树。如果hash(hash(f1) + hash(f2) + hash(f3)) = hash(hash(g1) + hash(g2) + hash(g3)),那么f1 = g1,f2 = g2f3 = g3

除了使构造和验证更容易之外,这种方法还允许您在文件集更改时节省计算。如果你已经存储了hash(f1)hash(f2),你想把f3添加到列表中,你只需要计算hash(f3),然后是新的哈希列表的哈希。这对于数据集的同步也非常有用。如果Alice想要向Bob传输文件,她可以先发送哈希,然后Bob验证他已经知道的哈希并告诉Alice, Alice只需要传输Bob还没有哈希的文件。

最新更新