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