我的文件有元数据空间。我想在其中存储用于完整性验证的哈希。问题是,一旦我存储了哈希,文件和哈希就会随之改变。
我完全理解,根据定义,使用md5 / sha等加密哈希方法是不可能的。
我也知道容器可以存储与内容分开的验证数据,如zip&合作。
我也知道可以单独计算哈希值并将其与文件一起发送,或者将其附加到末尾或客户端在计算哈希值时忽略它。
这不是我想要的。
我想知道是否有一种算法可以从数据中获取结果哈希值,其中包含哈希本身的结果。
它不需要加密或满足很多标准。它也可以基于一些启发式方法,在经过一段时间后提供所需的结果。
我真的不是很喜欢数学,但是不可能有一些真正先进的指数模多项式循环反向参考偏差使这成为可能吗?
如果没有,最新的(如果有的话)是针对它的证据吗?
我需要tis的原因是因为我希望(最终)与MP4文件一起存储哈希。它很复杂,但其他解决方案并不容易实现,因为文件遍历了一个设计非常糟糕的生产线......
答案 0 :(得分:7)
在某种程度上,可以使用CRC执行此操作。我过去所做的是在文件中留出4个字节作为CRC32的占位符,用零填充它们。然后我计算文件的CRC。
然后可以通过计算CRC多项式的Galois域中的数字来填充占位符字节以使文件的CRC等于任意固定常数。
(进一步详情可能但此时并不正确。你基本上需要在Galois字段中计算(CRC_desired - CRC_initial)* 2 -8 * byte_offset ,其中byte_offset是两者之间的字节数占位符字节和文件末尾。)
注意:根据@ KeithS的评论,这个解决方案不是为了防止故意篡改。我们在一个项目中使用它作为将嵌入式系统中的元数据绑定到用于编程的可执行文件的手段 - 嵌入式系统本身并不直接了解用于编程它的文件,因此无法计算CRC或散列本身 - 用于检测嵌入式系统与用于对其进行编程的文件之间的无意不匹配。 (在后来的系统中,我刚刚使用过UUID。)
答案 1 :(得分:2)
当然,这在很多方面都是可能的。但是,它无法阻止故意篡改。
例如,让
hash(X) = sum of all 32-bit (non-overlapping) blocks of X modulo 65521.
让
Z = X followed by the 32-bit unsigned integer (hash(X) * 65521)
然后
hash(Z) == hash(X) == last 32-bits of Z
这里的想法是,任何与0模65521一致的32位整数对X的散列都没有影响。然后,因为65521< 2 ^ 16,hash的范围小于2 ^ 16,并且至少有2 ^ 16个值小于2 ^ 32与0 modulo 65521一致。因此我们可以将哈希编码为不会影响的32位整数哈希。你实际上可以使用任何小于2 ^ 16的数字,65521恰好是最大的这样的素数。
答案 2 :(得分:1)
不,不可能。您要么是哈希ala md5sum的单独文件,要么嵌入式哈希仅用于文件的“数据”部分。
答案 3 :(得分:1)
我记得一个旧的DOS程序能够在文本文件中嵌入该文件的CRC值。但是,只有使用简单的哈希函数才能实现这一点 理论上你可以为任何类型的哈希函数创建这样的文件(给定足够的时间或正确的算法),攻击者将能够使用完全相同的方法。更重要的是,他会选择:准确地使用你的方法来获取这样的文件,或者只是为了摆脱支票。
这意味着现在你有两个问题而不是一个问题,两者都应该以相同的复杂性实现。由你来决定它是否值得。
编辑:您可以考虑哈希一些中间结果(如RAW解码输出,或特定于您的编解码器的东西)。通过这种方式,解码器无论如何都会拥有它,但对于另一个程序来说,计算起来会更加困难。答案 4 :(得分:0)
这取决于你对“哈希”的定义。正如你所说,显然有任何伪随机散列,这是不可能的(在合理的时间内)。
同样明显的是,你可以做到这一点,当然还有琐碎的“哈希”。例如,具有奇数个位的数据被设置为1到0的散列,并且偶数个1的散列为11。散列不会修改1位的奇数/偶数,因此当包含散列时,文件会对其进行散列。
答案 5 :(得分:0)
the nix package manager这样做的方式在计算哈希时你假装文件中哈希的内容是一些固定值,比如20 x
,而不是文件的哈希值那么你在那20个x
上写下哈希值,当你检查哈希值时,你会读到它并再次忽略它假装哈希值只是哈希值时20 x
的固定值
他们这样做是因为安装包的路径取决于整个包的散列,因此散列具有固定长度,他们将其设置为某个固定值,然后将其替换为真实散列并在验证时忽略他们放置的价值并假装它是固定值
但是如果你不使用这样的方法是不可能的