【发布时间】:2010-06-01 09:22:44
【问题描述】:
我正在编写一个 C# DKIM 验证器,但遇到了一个我无法解决的问题。现在我正在计算正文哈希,如Section 3.7 Computing the Message Hashes 中所述。我正在处理使用 Exchange 2010 传输代理 SDK 中的 EdgeTransportAsyncLogging 示例的修改版本转储的电子邮件。它不会在保存时转换电子邮件,而是根据 MessageID 打开一个文件并将原始数据转储到磁盘。
我能够使用以下代码成功计算Section A.2 中提供的示例电子邮件的正文哈希:
SHA256Managed hasher = new SHA256Managed();
ASCIIEncoding asciiEncoding = new ASCIIEncoding();
string rawFullMessage = File.ReadAllText(@"C:\Repositories\Sample-A.2.txt");
string headerDelimiter = "\r\n\r\n";
int headerEnd = rawFullMessage.IndexOf(headerDelimiter);
string header = rawFullMessage.Substring(0, headerEnd);
string body = rawFullMessage.Substring(headerEnd + headerDelimiter.Length);
byte[] bodyBytes = asciiEncoding.GetBytes(body);
byte[] bodyHash = hasher.ComputeHash(bodyBytes);
string bodyBase64 = Convert.ToBase64String(bodyHash);
string expectedBase64 = "2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=";
Console.WriteLine("Expected hash: {1}{0}Computed hash: {2}{0}Are equal: {3}",
Environment.NewLine, expectedBase64, bodyBase64, expectedBase64 == bodyBase64);
上面代码的输出是:
Expected hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Computed hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Are equal: True
现在,大多数电子邮件都带有c=relaxed/relaxed 设置,这要求您在散列和验证之前对正文和标题进行一些处理。当我正在处理它(未能让它工作)时,我终于遇到了一条带有c=simple/simple 的消息,这意味着您按原样处理整个正文,减去正文末尾的任何空CRLF。 (真的,Body Canonicalization 的规则很...simple。)
这里是real DKIM email(右键保存,浏览器吃掉结尾CRLF),使用简单算法签名(完全未修改)。现在,使用上面的代码并更新 expectedBase64 哈希,我得到以下结果:
Expected hash: VnGg12/s7xH3BraeN5LiiN+I2Ul/db5/jZYYgt4wEIw=
Computed hash: ISNNtgnFZxmW6iuey/3Qql5u6nflKPTke4sMXWMxNUw=
Are equal: False
预期的哈希值是来自DKIM-Signature 标头的bh= 字段的值。现在,第二个测试中使用的文件是 Exchange 2010 传输代理的直接原始输出。如果有这种倾向,可以查看修改后的EdgeTransportLogging.txt。
此时,无论我如何修改第二封电子邮件,更改文件末尾CRLF 的起始位置或数量,我都无法获得匹配的文件。让我担心的是,到目前为止,我无法验证 任何 正文哈希(简单或轻松),并且通过 Exchange 2010 处理 DKIM 可能不可行。
【问题讨论】:
-
@notandy 谢谢,我不再使用 Exchange,但我的问题不在于尝试签署电子邮件(这很容易),我的问题是尝试验证入站邮件的 DKIM 签名。据我所知,这是不可能的,因为没有办法让 Exchange 为您提供未经更改的主体供您散列。
标签: c# .net validation sha256 dkim