我的任务是从多个文件中计算哈希值。
我也已经知道每个单独文件的哈希值。
有两个方法:
hash(f1 + f2 + f3)
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)
- 8字节:
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 = g2
和f3 = g3
。
除了使构造和验证更容易之外,这种方法还允许您在文件集更改时节省计算。如果你已经存储了hash(f1)
和hash(f2)
,你想把f3
添加到列表中,你只需要计算hash(f3)
,然后是新的哈希列表的哈希。这对于数据集的同步也非常有用。如果Alice想要向Bob传输文件,她可以先发送哈希,然后Bob验证他已经知道的哈希并告诉Alice, Alice只需要传输Bob还没有哈希的文件。