是否可以按小块计算哈希?
Posted
技术标签:
【中文标题】是否可以按小块计算哈希?【英文标题】:Is it possible to compute a hash by small chunks? 【发布时间】:2021-12-30 06:23:06 【问题描述】:我目前正在研究低内存嵌入式系统的固件更新机制。
部分系统要求在发送文件之前对二进制文件进行哈希处理(使用 SHA-256)(添加了其他安全功能,但不影响此问题)。设备必须在验证此哈希之前对其进行验证,但内存非常低。它将以小块的形式接收数据,我想知道是否可以“即时”计算部分哈希,以避免在完全传输后再次加载整个二进制文件。
例如,假设要散列的数据是“part1part2part3”。完整数据的哈希为“hash”,“part1”的哈希为“hash1”,“part2”的哈希为“hash2”,“part3”的哈希为“hash3”。
我可以做任何数学运算来将部分散列转换为完整散列吗?类似的东西
hashReceived = hash
tempHash = operation(hash1,hash2)
tempHash = operation(tempHash, hash3)
if(hashReceived == tempHash)
... continue
else
... fail
我正在寻找 SHA-256 的数学属性(类似于分配属性),它可以在不破坏任何 SHA-256 属性的情况下允许此类行为。
【问题讨论】:
是的,这是可能的,至少在原则上是这样。 SHA 哈希是按顺序计算的,因此只要保留计算的状态,您就应该能够根据需要将计算分成块。 是的,您可以将数据流式传输到大多数语言的散列函数中。您需要哪种语言的解决方案? 【参考方案1】:您描述的方式是不可能的。您不能结合“子哈希”来确定完整的哈希。如果你能做到这一点,哈希将受到length-extension attacks 的约束并且不安全。 (此处的“安全”以相当精确和技术性的方式定义。请参阅 Stef 的链接,了解其他放宽此要求的散列方法。)
但是,正如问题的 cmets 所指出的,完全可以将数据流式传输到 SHA256 中,而无需将所有数据保存在内存中。这是计算散列函数的正常方式。 SHA256 适用于 64 字节的块大小。这就是您一次需要保存的所有数据,加上 32 个字节的状态。
大多数常见的哈希库都将其作为 API 的一部分。它通常看起来像:
hasher = create_hasher()
update_hash(hasher, data1)
update_hash(hasher, data2)
update_hash(hasher, data3)
final_hash = compute_hash(hasher)
本例中的hasher
每次调用update_hash
时都会改变其内部状态,然后在调用compute_hash
时完成哈希。对update_hash()
的调用不会分配任何新内存,并且在数据包用于更新哈希后无需保留它们。
【讨论】:
真的不可能吗?关于 crypto.stackexchange 的相关问题:Are there any practical implementation of a homomorphic hashing or signature scheme? @Stef 任何能够抵抗长度扩展攻击的东西都是不可能的(因为它是一种长度扩展攻击)。同态散列没有这个要求,但是“安全散列算法”标准有(这个问题需要 SHA-256)。所以你可以(理论上,虽然我不知道一个实用的)构建一个“安全数据验证哈希”来解决这个问题(正如你的链接描述的那样),它不能是 SHA-256 或任何其他 SHA。我已经更新了答案以更准确地说明这一点。 感谢您的回答,这正是我想要的!然后我会尝试将其集成到我们的解决方案中(使用 ST 的加密库)以上是关于是否可以按小块计算哈希?的主要内容,如果未能解决你的问题,请参考以下文章