Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法验证DKIM的正文哈希_C#_.net_Validation_Sha256_Dkim - Fatal编程技术网

C# 无法验证DKIM的正文哈希

C# 无法验证DKIM的正文哈希,c#,.net,validation,sha256,dkim,C#,.net,Validation,Sha256,Dkim,我正在编写一个C#DKIM验证器,遇到了一个我无法解决的问题。现在我正在计算body散列,如中所述。我正在处理使用Exchange 2010 Transport Agent SDK中EdgeTransportAsyncLogging示例的修改版本转储的电子邮件。它不会在保存时转换电子邮件,而是根据MessageID打开一个文件,并将原始数据转储到磁盘 我能够使用以下代码成功计算中提供的示例电子邮件的正文哈希: SHA256Managed hasher = new SHA256Managed();

我正在编写一个C#DKIM验证器,遇到了一个我无法解决的问题。现在我正在计算body散列,如中所述。我正在处理使用Exchange 2010 Transport Agent SDK中EdgeTransportAsyncLogging示例的修改版本转储的电子邮件。它不会在保存时转换电子邮件,而是根据MessageID打开一个文件,并将原始数据转储到磁盘

我能够使用以下代码成功计算中提供的示例电子邮件的正文哈希:

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
。(真的,身体规范化的规则非常

下面是使用简单算法(完全未修改)的签名(右键单击并保存,浏览器吃掉结尾
CRLF
)。现在,使用上述代码并更新
expectedBase64
哈希,我得到以下结果:

Expected hash: VnGg12/s7xH3BraeN5LiiN+I2Ul/db5/jZYYgt4wEIw=
Computed hash: ISNNtgnFZxmW6iuey/3Qql5u6nflKPTke4sMXWMxNUw=
Are equal: False
预期的散列是来自
DKIM签名
头的
bh=
字段的值。现在,第二个测试中使用的文件是来自Exchange2010传输代理的直接原始输出。如果有此倾向,您可以查看修改的


此时,无论我如何修改第二封电子邮件,更改文件末尾的
CRLF
的起始位置或编号,我都无法获得匹配的文件。让我担心的是,到目前为止,我无法验证任何正文散列(简单或轻松),并且通过Exchange 2010处理DKIM可能不可行。

我在python DKIM中尝试了这一点,但也发现正文散列不匹配

我认为Exchange可能没有在传输时提供实际字节,因此哈希不匹配。可能是将消息分解为mime部分,然后GetMimeReadStream为您提供了消息的有效表示形式,但不是最初发送的消息

也许还有另一个API可以提供真正的原始字节

或者,在这个过程中,消息已经被撕开,原始消息被丢弃,您需要更早地进行连接

您可能应该尝试通过将DKIM签名的消息发送到非Exchange服务器来拦截该消息,并查看该消息是否适用于您的代码
GetContentReadStream
可能有效吗


无论如何,我下一步要做的是尝试找到一个API,它可以为您逐个字节地提供所发送的内容。

您把它钉在了头上。据我所知,我收到了一封“大部分重新组装”的邮件,邮件中有足够多的变体,以防止它与本应匹配的邮件相匹配。虽然我还没有搜索所有内容,但看起来它们并没有提供一种获取原始字节的方法,因为这些字节要么是未管理的。看起来(目前)唯一的解决方案是实现一个中间SMTP服务器(如IIS),您可以在那里连接并处理它。在@notandy有一个解决方案,谢谢,我不再使用exchange,但我的问题不是尝试签署电子邮件(这很容易),我的问题是尝试验证入站邮件上的DKIM签名。据我所知,这是不可能的,因为没有办法得到交换来为你提供一个不变的身体供你散列。