使用 c# 计算 Content-MD5 HTTP 头文件值

Posted

技术标签:

【中文标题】使用 c# 计算 Content-MD5 HTTP 头文件值【英文标题】:Computing Content-MD5 HTTP header file value with c# 【发布时间】:2013-09-08 16:36:41 【问题描述】:

我正在实现将响应 HTTP 请求的服务的一部分,我要支持的标头之一是 Content-MD5。 RFC 声明以下关于 Content-MD5 计算:

要生成Content-MD5字段的值,MD5算法是 根据 MIME 实体对象的规范形式计算。在 特别是,这意味着发送方将 MD5 算法应用于 转换为规范形式之后的数据,之前 应用任何内容传输编码,并且接收器也 在撤消任何操作后,对规范形式应用 MD5 算法 内容传输编码。对于文本数据,这意味着 MD5 算法必须根据其规范形式的数据计算 换行适用,也就是说,其中每个换行都由 CR-LF 对。 MIME 的规范编码模型在 1的附录G。

MD5 算法的输出是一个 128 位的摘要。在查看时 网络字节顺序(大端顺序),这会产生一个 16 的序列 八位字节的二进制数据。这 16 个八位字节然后根据 base64 算法以获取放入的值 内容-MD5 字段。因此,如果应用 MD5 算法 在 MIME 实体的原始数据上生成具有 (不太可能)“检查完整性!”的值,然后是那个 MIME 实体的 标头可以包含字段

   Content-MD5:  Q2hlY2sgSW50ZWdyaXR5IQ==

(这不是来自 HTTP RFC,而是 referenced by it)

在这个阶段我没有做任何内容传输编码,所以这应该很简单,但我没有得到我期望的结果:

using System;
using System.Security.Cryptography;
using System.Text;

  //somewhere in the file...
  MD5 md5 = MD5.Create();
  responseBody = Encoding.ASCII.GetBytes("Check Integrity!");
  var hash = md5.ComputeHash(responseBody);
  string encodedHash = Convert.ToBase64String(hash);
  //now the following is true:
  encodedHash == "nwqq6b6ua/tTDk7B5M184w=="

知道这段代码哪里出错了吗?

【问题讨论】:

【参考方案1】:

代码没有问题,但我确实误读了 RFC:

因此,如果对一个原始数据应用 MD5 算法 MIME 实体导致摘要具有(不太可能)值为“检查 正直!”(...)

"Check Integrity!" 是(不太可能的)MD5 散列结果,而不是被散列的响应。字符串正好是 16 个 ASCII 字符长,这并非巧合。

更新后的验证码表现如预期:

var hash = Encoding.ASCII.GetBytes("Check Integrity!");
Assert.AreEqual(16, hash.Count()); // true
string encodedHash = Convert.ToBase64String(hash);
Assert.AreEqual(encodedHash, "Q2hlY2sgSW50ZWdyaXR5IQ=="); // true

【讨论】:

以上是关于使用 c# 计算 Content-MD5 HTTP 头文件值的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking 中的 Calc Content-MD5

在 Haxe 中为 AWS S3 REST 生成 Content-MD5

错误 s3 put/get ops with localstack:`The Content-MD5 you specified was invalid when execution`

nginx安装第三方模块file_md5

如何在 C# 中计算“五的中位数”?

如何使用c#计算两天内的日期时间? [复制]