【问题标题】:Order independent hashing顺序独立散列
【发布时间】:2017-06-07 22:24:36
【问题描述】:

我正在为键值数据创建键,方法是获取几条 (SHA256::Update 函数,它可以让您一次添加片段:

#include "sha.h"
...
byte outputBuf[CryptoPP::SHA256::DIGESTSIZE];
CryptoPP::SHA256 hash;
hash.Update(pData1, lenData1); // pData* can point to int, double or std::string
hash.Update(pData2, lenData2);
...
hash.Final(outputBuf);

我注意到对 Update 的调用顺序很重要(即,如果您更改两个 Update 语句的顺序,您将获得不同的哈希值)。我希望这是独立于订单的。所以:

  • CryptoPP 是否提供了执行此操作的方法?
  • 如果没有,您能否建议一种替代方法?到目前为止,我认为使用xor 组合参数会起作用。一个问题是,如果两条数据相同,它们就会相互抵消。您能预见到这方面的问题吗?

【问题讨论】:

  • 几乎每个好的散列(即使是非加密的)都将依赖于顺序。否则会以非常规律的模式导致可预见的碰撞,这是不好的。
  • 独立地对每个数据块进行一次散列,然后^ 将结果放在一起。当然,它很糟糕,并且缺少许多你想要的良好哈希的特性,但它是一个独立于顺序的哈希。
  • 只需提供一个带有命名参数(或具有命名成员的结构)的函数,并让函数担心散列它们的顺序。任何使散列顺序无关的方法都会增加冲突,也许相当显着。
  • 顺序独立性不仅会明显增加冲突的数量,而且会显着增加(因为 N 个字节有 N! 个排列,而 20! 大约是 10^18) .但更糟糕的是,如前所述,不仅存在冲突,而且它们以某种模式发生。另请注意,每个交换操作都存在使用 xor 作为哈希的“缺点”。逆元素将始终抵消。使用异或,这恰好是一个相同的块,但对于每个交换操作(例如a + b + (-b) = a)它都是相同的(具有一些不同的值)。这就是它的工作原理。
  • 这个问题似乎离题了,因为它更适合 crypto.stackexchange.com 或 security.stackexchange.com。

标签: c++ hash crypto++


【解决方案1】:

只有当您将{1, 2}{2, 1} 视为不同 输入时,有关异或会增加冲突次数的评论才是正确的。我想,你不需要,否则你不会想要一个与顺序无关的哈希。所以h({1, 2}) = h({2, 1}) 没有冲突,因为您提供相同的输入

最简单的解决方案是排序,而不是使用您最喜欢的哈希函数。它与您的散列函数一样安全(如果您愿意,请在 crypto.stackexchange.com 上确认)。

异或哈希绝对是一个坏主意,因为两个相等的元素会抵消。添加它们要好得多,但是对于两个相等的元素,最低有效位将为零(对于四个这样的元素,两位将为零,等等)。这可能是可以接受的。

请注意,任何此类方法都非常不安全,因为它可以更快地发现冲突(根据要求提供证明)。您可能需要也可能不需要安全性,但不要试图发明一种安全的方法,因为这实际上是不可能的(每个著名的散列函数背后都有很多人月的分析)。

【讨论】:

    猜你喜欢
    • 2017-03-27
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多