DKIM simplified and how it works (but not for beginners)

Lifting shrouds from IT-related mysteries is what we do here.

DKIM… yet another mys(t)ery to so many, but actually not that much rocket science as it seems.
Let me explain : 

Simplified as an acronym, DKIM stands for “Domain Keys Identified Mail” and is nothing more than “just another TXT record” in your DNS.
In a previous post, you could read up about SPF records and how they can diminish the amount of spam being sent FROM your domain name. DKIM takes this to a next step.
It’s the implementation of DKIM that will require some extra feedback from me, though.

Extremely simplified

Woodpecker.co explains DKIM as following :

“Take Game of Thrones to get the bigger picture of DKIM. Ned Stark is sending a raven with a message to king Robert. Everyone could take a piece of paper, write a message and sign it Ned Stark. But there’s a way to authenticate the message – the seal. Now, everyone knows that Ned’s seal is a direwolf (that’s the public key). But only Ned has the original seal and can set it on his messages (that’s the private key).”

Quite the analogy, if you’ve seen GoT (and no spoilers, even !)

 

What happens when using DKIM ?

The entire concept is based on encryption of a specific value that uses a public and a private key, that are generated in pairs and therefore cannot exist apart from each other.

The public value is stored (obviously) in a public location where all e-mail servers and clients can access it : the DNS server that holds your domain name (OVH, Skynet, Godaddy, Combell, …)

The private value is sent in an encrypted way over internet and can be verified through means of that private key, to check if it used the original correct signature.
It’s comparable to how an MD5 checksum works

(with the exception that at the time of this writing, DKIM can not yet be broken and it’s possible to “fake” an MD5 lol)
Image courtesy of postmarkapp.com

This hidden signature is then verified by the mail server, through which you send your signed mail, as well as all other mail servers where this message passes (in its original form).

Because…. the signature is added to the mail headers and is completely independant from how SPF records work, a proxy’ing mail server that just passes on your message, retains headers.
Theoretically, your mail could fail on an SPF, but could be perfectly valid on a DKIM basis !

 

Fool-proof ?

Is this method a fool-proof way of confirming ALL mails from your domain are safe now ?

A simple answer : NO.

DKIM is kind of the reverse of SPF, whereas SPF tells the receiving mail server what mail NOT to trust.
DKIM tells the receiving mail server that this specific mail, sent from this specific source is – in fact – OK to receive. DKIM does not guarantee that mails from your domain name, sent from a source other than the one defined in the key verification, are in fact safe, because the key in the verified mail message only counts for the specified source.

“Should I not bother to use DKIM, then ?”

You should still try to implement DKIM wherever possible, as all methods of securing your mail flow and getting spam/phishing mails out of this digital world, are most welcome.

 

What does DKIM look like & “comment ça marche” ?

Enough with the theory; let me explain how (and when) this works.

First of all, your own mail server, through which YOU send outgoing mail, has to have support for DKIM key generation.
Most ISPs (I think we can say “all ISPs”) will not use DKIM, as this would mean having to sign every friggin mail message that the millions of their customers send out on a daily basis.
All mail software would first have to talk on an encrypted basis to a public SMTP server to stuff that signed key in the mail header of their own mail message.
Seeing as most ISPs allow sending over their mailservers, without any authentication whatsoever, except for sending from their IP address range, this can ony mean : a big no-no.

Onward.

If your mail server supports DKIM (we’ll be using Microsoft 365 as an example), we can go ahead and create a DKIM.

https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/email-authentication-dkim-configure?view=o365-worldwide  explains in heavy detail how to create a DKIM pair on a M365 mail-based subscription (Exchange Online in short).
Go ahead and read the article.
The come back here, for a small moment of enlightenment.

All caught up?
Good.

The original private key is never shown and is only known to your very own mailserver.
You get to see – usually in the form of a next-next-next wizard – the entries you have to add as a CNAME record in your own DNS server that hosts the domain name from which you’re sending mail.

As cryptography goes, the mailserver recieves your request to send a mail to somebody.
Next, it adds a specific unique mail header to your outgoing mail, based on its own private key, in combination with the key known to the public (and thus shown in your DNS records, for others to reverse verify)

Before showing the layout of the DKIM record, let me show you what a signed mail header looks like.
If you’ve been following my instructions, you’ve already seen a DKIM record on the Microsoft website mentioned above, by the way :p

DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=newyork;
c=relaxed/simple; q=dns/txt; t=1117574938; x=1118006938;
h=from:to:subject:date:keywords:keywords;
bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;
b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR

Analysis time :

  • Every DKIM signed mail starts with “DKIM-Signature:”
  • The obvious part “v=1” defines the versioning (duh). Ironically at the time of writing, the version will always be “1”
  • “a” defines the signing algorithm, usually RSA-SHA or RSA-SHA256
  • “d” stands for the domain name of the sender
  • “s” is short for “selector” which can be found in the corresponding DNS record (in this case) newyork._domainkey.example.net 
  • “c” is the abbreviation for “canonicalization algorithm”. A tricky one to explain, but I’ll try my best.
    You can see it contains 2 values. They represent header/body and define the (dis)allowing of slight header changes in mail forwarding.
    “Relaxed” allows a certain change in the header (for instance when forwarding a mail).
    “Simple” just tells the receiving mail server, that no change in the mail header part is allowed for it to still be a trusted DKIM key.
  • “q” is for “query” and tells the receiving end how to perform the DKIM check.
    The q-part is optional. At the time of writing, the only valid entry here is “DNS/TXT”, which defines that a DNS lookup needs to be done, looking into a certain TXT field.
  • “t” is the timestamp
  • “x” falls together with the timestamp and stands for “expiration”, in case you have a fast-rotating key-pair in your DKIM setup and want to assure the receiving end of a higher security level.
  • h” lists the signed header fields …
  • …while “bh” is the hash for the body part of the mail
  • “b” is the actual signature data.

Should you totally want to geek out more on the RFC for DKIM, you can get your groove on at https://dkim.org/specs/rfc4871-dkimbase.html

 

The DNS record(s)

Why did I keep this part for last ?
You could see in the above example, that the RFC leaves space for a different way of reading your DKIM record.
For now, we don’t have a different technology other than DNS to exchange DKIM data, but if DKIM were to be upgrading, so to speak, the possibilities would not be limited to DNS.

 

The actual public key would look like this :

NAME : 
nameofyourselector._domainkey.example.net

TYPE : 
TXT

CONTENTS OF RECORD : 
v=DKIM1; k=rsa; p=KLJHLHkjhkhkluhiukhjiulYUHKJUIYUYNJKHLKHIOUHJhjkhkjhklhjkh

The content of this record will be provided by your mail server, when you go through the DKIM generating process

 

A different approach is the use of a CNAME record instead of a TXT record, where your key is stored elsewhere.
Depending on the suggestion your mail server gives you, you’ll implement one or the other.

Your CNAME record could look like this :

NAME : 
nameofyourselector._domainkey.example.net

TYPE : 
CNAME

CONTENTS OF RECORD : 
heresmykey.something.anotherdomain.com

 

There we have it.
Theory and samples.

If you have any questions, don’t hesitate to contact me by mail, postal pigeon, smoke signal, …

Zuper out

 

Handy websites concerning this subject :

  • https://mxtoolbox.com/
  • https://easydmarc.com/tools/dkim-record-generator

 

Leave a Reply

Your email address will not be published. Required fields are marked *