是否可以复制.NET HashAlgorithm(用于重复的增量散列结果)?

Mar*_* Ba 11 c# md5 clone hashalgorithm

我有以下用例:

  • 从文件中读取n个字节
  • 计算这些n个字节的(MD5)哈希值
  • 从文件中读取下一个m字节
  • 计算(MD5)哈希,文件最多为n + m个字节

增量散列文件不是问题,只需调用TransformBlockTransformFinalBlock.

问题是我需要多个哈希的数据共享它的起始字节,但在我调用TransformFinalBlock读取Hash第一个n字节后,我不能继续使用相同的对象进行哈希并需要一个新的字节.

在搜索问题时,我发现PythonOpenSSL都可以选择复制散列对象,以实现此目的:

hash.copy()

返回哈希对象的副本("克隆").这可以用于有效地计算共享公共初始子字符串的字符串的摘要.

 

EVP_MD_CTX_copy_ex()可用于将消息摘要状态从in复制到out.如果要散列的大量数据仅在最后几个字节中有所不同,这非常有用.必须在调用此函数之前初始化out.

正如我可能搜索的那样,我找不到任何包含库存C#HashAlgorithm的东西,它允许我调用它的方法之前有效地Clone()= =复制这样的对象- 然后继续用克隆散列其余的数据.TransformFinalBlock

我找到了一个MD5C#参考实现,可以简单地适应支持克隆(*),但是我更倾向于使用那些而不是将这样的东西引入代码库.

(*)实际上,据我所知,任何哈希算法(与加密/解密相反)我都很难检查,因为这种算法所具有的所有状态都是一种摘要形式.

所以我在这里遗漏了一些东西,或者标准的C#/ .NET接口实际上是不是提供了复制哈希对象的方法?


另一个数据点:

微软自己加密服务原生API 有一个功能CryptDuplicateHash,其中的文档状态,引用:

CryptDuplicateHash函数可用于创建以相同内容开头的两个不同内容的单独哈希.

自Windows XP以来一直存在.: - |


注意wrt.MD5:用例不具有加密敏感性.只是可靠的文件校验和.

Mar*_* Ba 3

库存 .NET 库不允许这样做。伤心。无论如何,有几种选择:

  • MD5Managed纯.NET(“默认”MD5 RSA 许可证)
  • ClonableHash通过 PInvoke 包装 MS Crypto API(可能需要一些工作从Org.Mentalis命名空间中提取它,但许可证是允许的)

例如,也可以将C++ 实现包装在 C++/CLI 包装器中 - 初步测试表明,这似乎比普通的 .NET 库快得多,但请不要相信我的话。


此后,我自己还编写/改编了一个基于 C++ 的解决方案: https: //github.com/bilbothebaggins/md5cpp

由于需求发生了变化,它尚未投入生产,但这是一个很好的练习,我认为它运行得很好。(除了它不是纯 C# 实现。)