Cisco Blogs


Cisco Blog > Security

Common Errors Causing DKIM Verification Failures

Cisco recently upgraded its email infrastructure to use our IronPort email security appliances to apply and verify DomainKeys Identified Mail (DKIM) signatures on outgoing and incoming email. We had previously been using a prototype implementation of DKIM that we had begun early in the process of standardizing DKIM. In the process, they made available to me some information on DKIM signature verification successes and failures. While we had previously published information on DKIM signature verification showing the increasing deployment of DKIM signing, this is the first time that we have had comprehensive information on signatures that fail to verify. The study involved about 14.2 million messages with DKIM signatures, 5.33% of which failed to verify. The messages came from 16,797 different domains, 10,968 (65%) of which had 100% verification rates and 2,899 of which failed consistently.

The breakdown of the verification failures is as follows:

Causes of DKIM Failures

Error

% Messages

% Domains

Signature did not verify

50.98

59.75

Body hash did not verify

21.31

25.99

Inapplicable key

11.70

8.46

Syntax error

5.30

3.40

Key query timeout

4.70

17.91

No key for signature

4.32

8.59

Invalid tag value in public key record

1.41

0.34

Inappropriate key algorithm

0.23

0.50

Invalid public key

0.03

0.65

Unsupported record version

0.02

0.43

Public key record missing required tag

0.01

0.12

Inappropriate hash algorithm

0.00

0.02

Duplicate tag

0.00

0.02

[Note that % Messages is the percent of messages that failed authentication having the specified error. % Domains adds to >100% because some domains had more than one type of error.]

Signature/Body Hash did not verify: As expected, the majority of verification failures are due to signature and message body hash verification failures. Body hash verification errors indicate that the body of the message does not agree with the hash (digest) value in the signature. Signature verification errors indicate that the signature value does not correctly verify the signed header fields (including the signature itself) on the message. There are several causes for these two errors: the message may have been modified (perhaps by a mailing list or forwarder) in transit; the signature or hash values may have been calculated or applied incorrectly by the signer; the wrong public key value may have been published in DNS; or the message may have been spoofed by an entity not in possession of the private key needed to calculate a correct signature. It is very hard to distinguish these causes by analysis of the message, although the origin IP address may provide some helpful forensics in the case of spoofing. However, for privacy reasons we don’t have access to the messages themselves, so any such analysis isn’t possible.

But there is a surprising number of messages whose signatures don’t verify for other reasons, often because of easily avoided configuration errors in the public key (selector) records published in DNS. We were able to examine a sample of these selectors, which revealed a few patterns.

1. Inapplicable key: One of the design considerations for DKIM was to make its key records compatible with the earlier DomainKeys specification. While there is a great deal of compatibility, one difference is the interpretation of the g= value, which is used as a constraint on the local part of the i= value (signing address) in the signature. In DomainKeys, a key containing “g=;” (a null g= value) is interpreted to match any address; in DKIM, it is interpreted to match no address. Unfortunately, there is an example in section 3.2.3 of the DomainKeys specification that shows a selector with a null value, and some domains that are signing with both DomainKeys and DKIM are using “g=;”. The solution to this is simple: simply remove the g= tag from the key, and it will be compatible with both DomainKeys and DKIM. One reason that the number of domains and messages for this error is so high is that an email-sending provider has been publishing their customers’ keys in this way. I have contacted them, and they are presumably in the process of fixing the problem.

2. Syntax error: This represents a miscellaneous error in the formation of the key record. One of the main errors that I have seen is improper quoting of values in the key record with the backslash character. To see how this might happen, consider a key record with the following contents:

k=rsa; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALl9ZT9erT0fcVzYKgn
UkiTedPnK/sy5HwPXFD20zyGQeSlntJWIrIff5/QOhJdh8df+IZOmDK2RvYh
VZSxtCB3gBvlgo4FwERBWUNJpoQRfQ2xamEsIMSaujEp4ymC3pwIDAQAB

 

This would be displayed by the common DNS query tool “dig” as follows:

$ dig +short selectorname._domainkey.example.com txt
"k=rsa; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALl9ZT9erT0fcVzYK
gnUkiTedPnK/sy5HwPXFD20zyGQeSlntJWIrIff5/QOhJdh8df+IZOmDK2Rv
YhVZSxtCB3gBvlgo4FwERBWUNJpoQRfQ2xamEsIMSaujEp4ymC3pwIDAQAB"

 

Note the insertion of the backslash in the output from the command. This isn’t really part of the DNS record, it’s just added in the output from the command. Some domains therefore think that it’s necessary to quote the semicolon with a backslash and/or to include extra quotes resulting in key records that look something like the following:

$ dig +short badselector._domainkey.example.com txt
""""g=; k=rsa; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAO9rW0eB
Y62hhG43PUyHmEH5f1PNMON1UBdv2ZdtoRy57GtQNMTaTbHlOvuBWdu5fHRn
6Up/Vs6sL1IW3c0+qdUCAwEAAQ==""""

 

In a few cases, the intended public key record wasn’t found, but another record, such as a wildcard, was returned in its place, resulting in a syntax error.

3. Key query timeout: These are generally transient errors caused by the DNS infrastructure, and not a concern unless they’re very numerous. Domains should make sure that all of the listed name servers for their domain are responding.

4. No key for signature: This one is pretty simple. No key (selector record) was found in DNS for a signature on a message. This could be caused by a simple failure of the signing domain to publish a key (or to publish it in the right place), or by someone attempting to forge a signature when there is no key present.

5. Invalid tag value: This is sometimes caused by a missing semicolon after a tag value, e.g. “g=* k=rsa;…” or by the aforementioned backslash problem, such as:

$ dig +short bad._domainkey.example.com txt
"v=DKIM1; k=rsa; h=sha1; p=MHwwDQYJKoZIhvcNAQEBBQAD
awAwaAJhAMXn1N0rBrjQNku3O2sr8jBRHzsBobo3Mdwviw6IPndp3ztg+7HB
x9InQGOCpbUOHR8Yt6Q5r9PuqFS+y33C+LzHyOvkEc+u6bKIdq4n1dO+Dow+
upujKK1za5xvIbYAJQIDAQAB"

 

6. Inappropriate key algorithm: This also generally results from the backslash problem, and is reported when the k= tag occurs first in the key record. It is reported in this way because the k=rsa; would match the key algorithm “rsa”” in the signature, but of course the signature uses the key algorithm named “rsa”, not “rsa””.

7. Invalid public key: Some of these are easy to spot (key the wrong length) but others are hard to diagnose by inspection. Some of the keys causing this error seem to have been truncated; make sure that the entire public key is pasted into the DNS record. Quite a few of these errors came from domains with very similar sounding names and private domain registration records, so they might have only been trying to make it appear that they were signing their messages.

8. Unsupported record version: This generally occurs if the public key record doesn’t exist but there is a wildcard, typically from an SPF or SenderID record, in a higher domain. It results from the detection of a string such as “v=spf1″ rather than the required DKIM1 value for the key string.

9. Public key record missing required tag: This results from domains publishing “k=rsa” as their selector record. Clearly, these domains aren’t trying very hard.


Nearly all of these errors are easy to catch with the testing tools available, such as test reflectors. A list of mail reflectors available for checking DKIM signatures can be found at http://testing.dkim.org/reflector.html.

When deploying DKIM signing, it’s worth the trouble to check and make sure that the signatures are verifying properly.

In an effort to keep conversations fresh, Cisco Blogs closes comments after 60 days. Please visit the Cisco Blogs hub page for the latest content.

4 Comments.


  1. These are very interesting statistics.Could it be possible that verification failures are due to simple and relaxed canocalization being misused/swapped?

       0 likes

  2. Jim Fenton

    Andries,Canonicalization errors in calculating the signature and/or body hash are indeed another possible source of verification failures. Diagnosing those errors would again require access to the message content, which I don’t have. But these are also detected using test email reflectors, which everyone should be testing with, but obviously aren’t.

       0 likes

  3. Hi Jim,Back when I first implemented DKIM on a custom e-mail system, none of the reflectors I tried worked. Apparently (irony ahead), due to e-mail abuse. I’m not sure any of the deflectors would catch this, as normal testing already offers 18 reasons why a signature is not valid.

       0 likes

  4. Jim Fenton

    Andries,I can relate to the irony about reflector abuse, since I had to shut down the testing.dkim.org reflector for just that reason. I have also run into reflectors that have various restrictions on their use (such as not accepting mail from mail servers that don’t have good reverse DNS records) in order to counter abuse. But as far as I know there are still reflectors that are running; report any that aren’t to me and I’ll correct the reflector list on the website.I’m not aware whether any reflectors check for these types of selector record errors. An alternative approach for this class of error might be a web-based interface for submitting a selector name and domain for a syntax check. That approach would be a lot less subject to abuse than the reflectors are.

       0 likes