dkim implementation details

The idea behind dkim is simple. You add a “DKIM-Signature:” in your email message. The stmp server receiving the email checks the header, pulls the dns record of the domain, then verifies whether the header is valid. If not valid, it may reject your email because your email message has been tempered during transmission.

A “DKIM-Signature:” header looks like this:

DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=simple/simple; d=myprogrammingnotes.com; s=default;
  h=Date:Subject:To:From; bh=xxxxxxxxxxxxxxx;
  t=1856756658;
  b=yyyyyyyyyyy;

All the tags except the t tag are required. The t tag is optional but recommended. The bh tag is the sha256 hash of the body of the message(i.e., the content after the first occurrence of “\r\n\r\n”). The b tag is the signature by signing the header indicated in the h tag with a private key.

What is vague here is the computation of the sha256 hash of the headers. What is exactly the headers’ content? In what order are the headers arranged? These must be strictly specified because a difference of a bit will lead to a totally different resulted hash.

Now,the answer to the question what exactly the content of header that is used to compute the hash: it is the entire header including the header name and header value and including the ending “\r\n”. Some guys remove the space between the colon and the first printable character of the header value to compute the hash, which is wrong. Keep all characters in the header including spaces.

As to the order of the headers, you can arrange the headers in arbitrary order, just specify the order in the h tag, i.e., the order of headers in the h tag really matters. The smtp server receiving the email will arrange the headers in the same order and compute the hash.

The meanest thing is that the header hash is computed out from not only the specified headers in the h tag, but also the DKIM-Signature itself. Hek, the b tag’s value is not available yet. How is the DKIM-Signature used to compute the hash? Well, the implementer should construct a temporary DKIM-Signature with all tags ready but the b tag which is set an empty value, i.e., “b=;” The constructed DKIM-Signature header should be put after all specified headers to compute the hash. At the receiver, the smtp server should remove the value of the b tag to compute the hash.

If you like my content, please consider buying me a coffee. Buy me a coffeeBuy me a coffee Thank you for your support!

Leave a Reply