title: Unable to verify body hash for DKIM
body: <p>I'm writing a C# DKIM validator and have come across a problem that I cannot solve. Right now I am working on calculating the body hash, as described in <a href="http://dkim.org/specs/rfc4871-dkimbase.html#rfc.section.3.7" rel="nofollow noreferrer" title="Section 3.7 Computing the Message Hashes">Section 3.7 Computing the Message Hashes</a>. I am working with emails that I have dumped using a modified version of EdgeTransportAsyncLogging sample in the Exchange 2010 Transport Agent SDK. Instead of converting the emails when saving, it just opens a file based on the MessageID and dumps the raw data to disk.</p>
  
  <p>I am able to successfully compute the body hash of the sample email provided in <a href="http://dkim.org/specs/rfc4871-dkimbase.html#rfc.section.A.2" rel="nofollow noreferrer" title="Section A.2 The email is signed">Section A.2</a> using the following code:</p>
  
  <pre><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);
  </code></pre>
  
  <p>The output from the above code is:</p>
  
  <pre><code>Expected hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
  Computed hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
  Are equal: True
  </code></pre>
  
  <p>Now, most emails come across with the <code>c=relaxed/relaxed</code> setting, which requires you to do some work on the body and header before hashing and verifying. And while I was working on it (failing to get it to work) I finally came across a message with <code>c=simple/simple</code> which means that you process the whole body as is minus any empty <code>CRLF</code> at the end of the body. (Really, the rules for Body Canonicalization are quite ... <a href="http://dkim.org/specs/rfc4871-dkimbase.html#rfc.section.3.4.3" rel="nofollow noreferrer" title="Section 3.4.3 The 'simple' Body Canonicalization Algorithm">simple</a>.)</p>
  
  <p>Here is the <a href="http://www.gibixonline.com/media/stackoverflow/dkim-real-email.txt" rel="nofollow noreferrer" title="Real DKIM Email">real DKIM email</a> (right click and save it, the browsers eat the ending <code>CRLF</code>) with a signature using the simple algorithm (completely unmodified). Now, using the above code and updating the <code>expectedBase64</code> hash I get the following results:</p>
  
  <pre><code>Expected hash: VnGg12/s7xH3BraeN5LiiN+I2Ul/db5/jZYYgt4wEIw=
  Computed hash: ISNNtgnFZxmW6iuey/3Qql5u6nflKPTke4sMXWMxNUw=
  Are equal: False
  </code></pre>
  
  <p>The expected hash is the value from the <code>bh=</code> field of the <code>DKIM-Signature</code> header. Now, the file used in the second test is a direct raw output from the Exchange 2010 Transport Agent. If so inclined, you can view the modified <a href="http://www.gibixonline.com/media/stackoverflow/EdgeTransportLogging.txt" rel="nofollow noreferrer" title="Edge Transport Logging">EdgeTransportLogging.txt</a>.</p>
  
  <p>At this point, no matter how I modify the second email, changing the start position or number of <code>CRLF</code> at the end of the file I cannot get the files to match. What worries me is that I have been unable to validate <em>any</em> body hash so far (simple or relaxed) and that it may not be feasible to process DKIM through Exchange 2010.</p>