AWS Messaging & Targeting Blog

DKIM Troubleshooting Series: Authentication Considerations

Hi, and welcome to another entry in the Amazon SES DKIM troubleshooting series. So far we have focused on technical issues, but now it’s time to take a step back and look at the bigger picture. Exactly why did we go to all this trouble in setting up DKIM for our domain?

My emails are signed and the signature validates. Does this mean I’m safe from spoofing attacks?

Even if all our email is DKIM signed and validated by all ISPs, this is no time to rest. The world is full of ethically dubious people who want to impersonate us and steal our customers, and DKIM is only step one in protecting ourselves.

So what exactly is DKIM doing to help us with this? The way this standard ensures the integrity of our emails is to calculate a hash of the message’s body and some of its headers, and then to digitally sign the hash. As long as the private key is kept secure, and the public key is accessible through DNS, the DKIM signature gives ISPs confidence that the domain that signs the message acknowledges its content through the signature. Let’s have another look at the DKIM signature to see exactly what we’re talking about:

DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple;

The "d" tag represents the domain that signs the email. In this case that would be our own domain, This domain takes responsibility for the email, guaranteeing its integrity through the signature. The "h" tag contains a list of all of the headers of this email that are signed (and thus have their integrity guaranteed) by the signing domain. The "bh" tag is the result of a hash function applied to the email’s body (very useful to ensure that the content itself hasn’t been tampered with). Finally, the "b" tag is the actual signature itself, applied to the body hash and headers. If that checks out, then both the message body and all of the headers included in the "h" tag are considered to be authenticated by the signing domain.

That’s all very nice, but how does it stop an attacker?

The hashing and key encryption algorithms we use are well known, so surely anyone can generate their own key pair and calculate the signature themselves, right? In fact… this is actually true. Anyone can sign any email with a DKIM signature, the problem is getting ISPs to trust that that signature is ours and not the attacker’s. The key here is in the "s" and "d" tags of the signature. The "d" tag is our domain, and the "s" (or "selector") tag indicates which of our domain’s signing keys has been used for this particular email. It’s these two tags that help build the location of the public key in DNS and form the obstacle in the attacker’s path. In this signature’s case, any ISP that wants to validate our email will try to retrieve the public key from a record ( <selector>._domainkey.<domain> ). An attacker can calculate hashes and signatures all they want but they won’t have permission to publish any key they control into our DNS, so they will never be able to compute a signature that has our domain as the "d" tag (and thus has its integrity guaranteed by us). DNS spoofing, it turns out, is not so easy to perform (although it has happened)! With only the public key visible in DNS, it is not computationally easy for any attacker to deduce the private part. Just in case, SES regularly rotates the keys, to thwart any such attempt.

Setting up DMARC can also signal ISPs to drop all emails that aren’t authenticated (via DKIM or SPF). If an attacker wants to impersonate our domain they can either put in a broken signature or no signature at all. In both cases, DMARC signals ISPs to quarantine (put in the Spam folder) or drop those emails. That is definitely a good step forward in dealing with phishing spam!

SES also offers other forms of authentication such as SPF, which are highly recommended and will further improve our security.

Next steps

In the next blog entry, we will have a look at another email-related concept that is indirectly influenced by DKIM: deliverability.