Failed to check hash for DKIM

I am writing a C # DKIM validator and have encountered a problem that I cannot solve. Right now I'm working on calculating the hash of the body as described in Section 3.7 Calculating the hash of messages.I'm working with emails that I dumped using a modified version of the EdgeTransportAsyncLogging example in the Exchange 2010 Transport Agent SDK. Instead of converting emails on save, it just opens the file based on the MessageID and dumps the raw data to disk.

I can successfully compute the hash hash of the sample file provided in Section A.2 using the following code:

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);

      

Output from the above code:

Expected hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Computed hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Are equal: True

      

Most emails now c=relaxed/relaxed

come with a parameter that requires you to do some body and header work before hashing and validation. And while I was working on it (without getting it to work), I finally stumbled upon a post with help c=simple/simple

, which means you treat the whole body as minus any empty CRLF

at the end of the body. (Indeed, the rules for canonizing the body canon are pretty ... simple .)

Here is a real DKIM email (right click and save it, browsers will eat the ending CRLF

) with a signature using a simple algorithm (completely unmodified). Now, using the above code and updating the hash expectedBase64

, I get the following results:

Expected hash: VnGg12/s7xH3BraeN5LiiN+I2Ul/db5/jZYYgt4wEIw=
Computed hash: ISNNtgnFZxmW6iuey/3Qql5u6nflKPTke4sMXWMxNUw=
Are equal: False

      

The expected hash is the value from the bh=

header field DKIM-Signature

. Now the file used in the second test is the direct original output from the Exchange 2010 Transport Agent. If so, you can view the modified EdgeTransportLogging.txt .

At this point, no matter how I change the second letter by changing the starting position or the number CRLF

at the end of the file, I cannot get the files to match. My concern is that I have not yet been able to verify any body hash (simple or casual) and that it may not be possible for DKIM through Exchange 2010.

+2


a source to share


1 answer


I tried this in python-dkim and I also have a hash object mismatch.

I think maybe Exchange is GetMimeReadStream

not giving you the actual bytes as they are transferred, so the hash doesn't match. It probably parsed the message into its mime part, and then GetMimeReadStream gives you a valid representation of the message, but not the one it was originally sent with.

Perhaps there is another API that will give you the actual raw bytes?



Or perhaps by this point in the process, the message has been ripped and the original message has been thrown, and you need to hook it earlier.

You should probably try intercepting the DKIM signed message by sending it to a non-Exchange server and see if that works with your code. GetContentReadStream

can work?

Anyway, what I'm going to do next is try to find an API that will give you byte for byte what was sent.

+1


a source







All Articles