Protobuf的GetHashCode到处都是一样的吗?

时间:2017-07-07 02:32:26

标签: hash protocol-buffers

我注意到我在GetHashCode()文件中生成的C#类中有.proto。为了更难以篡改数据,我想计算哈希码,将其与数据一起发送。然后我可以在目的地再次计算哈希值。

我的方法是在proto定义中有一个哈希字段,但在计算哈希之前,我会将其保留为0,计算它,将其放入并序列化。在目标处,将记住哈希值,将其设为0,然后计算新哈希以检查完整性。

接收端是JavaScript:

  • 目的地的哈希生成函数会产生相同的结果吗?
  • 如果使用新字段更新了.proto文件,到处生成了新类,那么旧消息会散列到相同的结果吗?

我知道MD5,但我认为它需要在二进制文件完成后生成,如果我这样做,我不能将MD5与数据一起包含。

我仍然会在此基础上加密,但万一有人设法解密数据,他无法轻易改变其中某些部分来欺骗接收者。

1 个答案:

答案 0 :(得分:1)

不,你不能那样使用GetHashCode()。它不是protobuf概念,而是存在于所有.NET托管类型中。首先,并非每个对象都覆盖此方法,如果不是,则对于类,它代表引用/实例,而不是内容(就像Equals一样默认情况下)。如果它被覆盖,那么每次在同一app-domain 时,它都会产生相同的值,但不要求它在不同的运行中产生相同的值。它是否依赖于实现和您使用的确切框架(假设使用string.GetHashCode之类的东西)。

但另一个问题是目标框架中的代码没有匹配的方法,即使它确实如此:也无法访问string.GetHashCode之类的相同实现

所以不:不要将此用于此目的。它没有这样做。

作为一个具体示例:string.GetHashCode之类的内容为相同的字符串生成不同的值,具体取决于操作系统和.NET版本。它甚至不会完全在.NET端点上做你想要的。

作为一个简单的例子,请考虑:

static void Main()
{
    Console.WriteLine("abc".GetHashCode());
    Console.WriteLine("abc".GetHashCode());
    Console.WriteLine("abc".GetHashCode());
}

如果我跑了一次,我得到:

518228267
518228267
518228267

所以你可能会想“啊,是的,GetHashCode()每次给出相同的值”。然而,它比这更微妙。在.NET的最新版本中,这是在app-startup 播种的,所以如果我再次运行它,我会得到:

-177712234
-177712234
-177712234

然后

-59760352
-59760352
-59760352

等。这样做的部分原因是为了避免人们依赖于GetHashCode()在运行之间是相同的,部分是为了防止人们能够使用已知具有相同哈希码的字符串集作为攻击向量来强调字典(强制它们使用回退行为) - 例如DDOS攻击Web服务器。如果静态外部代码无法预测哈希值,则此攻击向量将消失。