DKIM
DKIM is
DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message that is in transit. The organization is a handler of the message, either as its originator or as an intermediary. Their reputation is the basis for evaluating whether to trust the message for further handling, such as delivery. Technically DKIM provides a method for validating a domain name identity that is associated with a message through cryptographic authentication.
—dkim.org
The broad thrust is that the owner of a domain publishes (in the DNS) a public key. When email is sent by the domain's servers it is signed with the private key and an email header added. The recipient can then confirm that the email went through an organisation that has the private key associated with the domain.
Like SPF, this is for the benefit of the recipient and is created by the domain wonder for the common good.
In particular, you, the sender, specify a list of headers and a cryptographic signature of those headers. I, the recipient, can verify that the hash of those headers was signed by the key associated with the domain.
Example
As a real-world example, the DKIM header might look like:
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; s=key-name; d=example.com; h=List-Unsubscribe:List-Id:MIME-Version:To:From:Subject:Content-Type:Message-ID:Date; i=some.user@example.com; bh=rKoGIRu2K+rJCnnDVe3Hu9sCbGE=; b=GkPNpPAyGY0InBbUQlonUUedp12isOLveku/UTCtrGEDxzm+Cye4oBPKyprLOd4hTa+2oXmcbh6V OwMBRdPBl0vyDEBjOPww6T7YdWS4syoObZICFTZJHfofnIPnedjArWCrjxCnornszr05tj4HP4Ph bar82MiGFmTycBRgezo=
which we can re-write more legibly as:
v=1 a=rsa-sha1 c=relaxed/relaxed s=key-name d=example.com h=List-Unsubscribe:List-Id:MIME-Version:To:From:Subject:Content-Type:Message-ID:Date i=some.user@example.com bh=rKoGIRu2K+rJCnnDVe3Hu9sCbGE= b=GkPNpPAyGY0InBbUQlonUUedp12isOLveku/UTCtrGEDxzm+Cye4oBPKyprLOd4hTa+2oXmcbh6V OwMBRdPBl0vyDEBjOPww6T7YdWS4syoObZICFTZJHfofnIPnedjArWCrjxCnornszr05tj4HP4Ph bar82MiGFmTycBRgezo=
Of these tags, notable ones are:
s -- the selector
Used in combination with d, the domain, to find the associated public key for this message. It will be a DNS TXT record on s._domainkey.d, in this case, key-name._domainkey.example.com.
Note
_domainkey is a fixed string.
The use of a selector allows the sending domain to cycle through a number of possible keys over time (if a key were compromised or obsoleted or whatever).
The selector might be some sort of unique identifier, e.g. 1F519C68-B5EE-22E4-8A48-05D221EEA013.
d -- the domain
The specification for choosing the domain name suggests that the domain should be related to the role of the DKIM signing entity. You might indicate marketing, newsletter or sent on behalf of etc..
So a sales email from some.user@example.com might be signed with the sales.example.com DKIM entity. The DKIM public key will be the TXT record at s._domainkey.sales.example.com.
Similarly, if Example Inc was managing mail on behalf of Global Search Corp then an email from some.user@search.example might be signed by Example Inc's global-search.example.com DKIM entity. So, even though the body header says From: some.user@search.example the DKIM-Signature might reference d=global-search.example.com.
Of course, you might just be example.com.
h -- the set of headers that have been used for the signature
The DKIM-Signature is implicitly included in this list (with the b tag an empty string otherwise the value would constantly change!).
If a header occurs multiple times it needs to appear in this tag multiple times (although it's not clear what happens if the numbers of each do not tally).
i -- the identity of the sender
This is a field for the use of the sender in case of feedback about abuse. It can look a bit like an email address or a domain (both related to d) but need not be a valid email address or domain.
bh -- body hash
b -- the signature itself (of the headers, implicitly including the body through the DKIM-Signature header which includes bh, the hash of the body).
MIME
DKIM is not MIME-aware. This is a potential problem as the MIME specification allows a mail server to change to a different character set thus breaking the DKIM signature.
This doesn't appear to be a problem in practice.
Mailing Lists
Mailing list usually append a footer (often called a signature but not a cryptographic signature).
Extending the body will obviously break the body hash so there is another tag, l, which indicates how many bytes the body hash includes. If the message is DKIM-signed with a length tag before arriving at the mailing list server then any footer the mailing list server adds will not affect the DKIM signature.
If there is no length then the mailing list footer will break the DKIM signature.
If there is no DKIM signature, the mailing list could add one!
SpamAssassin
SpamAssassin plays a neat trick with DKIM headers.
If the header exists then the message is marked as being X points more spammy. (Counter-intuitive!)
If the signature verifies then the message is marked as being -X points more spammy. That is, a verified DKIM signature has a nett-spamminess of 0.
Obsolete Header
You might well see DomainKey-Signature alongside DKIM-Signature. DomainKey was the original implementation, superceded by DKIM. It seems to be the norm to generate both headers.
Field Observations
Anecdotal evidence suggests that spam that gets through to my inbox has valid DKIM signatures. That means the spammers have either compromised the sender system or they have access to the DNS to set/update the DKIM keys.
Document Actions