Understanding DKIM
DomainKeys Identified Mail (DKIM) is an email authentication protocol that allows a sending mail server to cryptographically sign outgoing messages. The receiving server can verify the signature by looking up the sender's public key in DNS. If the signature is valid, the receiver knows that the message was authorized by the domain owner and that the message content was not altered in transit.
DKIM addresses a gap that SPF (Sender Policy Framework) cannot fill. While SPF verifies that a message came from an authorized IP address, it says nothing about whether the message body or headers were tampered with after leaving the sending server. DKIM provides integrity verification: if even a single character of the signed content changes, the signature becomes invalid. Together with SPF and DMARC, DKIM forms the backbone of modern email authentication.
How DKIM Works
The DKIM signing and verification process follows these steps:
- Key pair generation: The domain owner generates an RSA or Ed25519 key pair. The private key is installed on the sending mail server. The public key is published as a DNS TXT record.
- Message signing: When the mail server sends a message, it selects specific headers and the message body, generates a hash of these components, and then encrypts the hash using the private key. The result is added as a
DKIM-Signatureheader. - Message delivery: The email travels across the internet with the DKIM-Signature header intact.
- Signature verification: The receiving server reads the DKIM-Signature header, extracts the domain and selector, queries DNS for the public key, and uses it to decrypt the signature hash. It then independently hashes the same headers and body and compares the two hashes.
- Result: If the hashes match, DKIM passes. If they differ, the message either was tampered with or the signature is invalid.
The DKIM-Signature Header
Every DKIM-signed email contains a DKIM-Signature header with several important tags:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=selector1;
h=from:to:subject:date:message-id;
bh=base64encodedBodyHash;
b=base64encodedSignature
The key tags are:
- v=1: The DKIM version. Currently always 1.
- a=: The signing algorithm.
rsa-sha256is the most common.ed25519-sha256is a newer, more efficient alternative. - c=: The canonicalization method for header and body.
relaxed/relaxedis recommended because it tolerates minor modifications (whitespace changes, header folding) that can occur during transit. - d=: The signing domain. This is the domain that claims responsibility for the message.
- s=: The selector, which identifies which public key to retrieve from DNS.
- h=: The list of headers included in the signature. At minimum, the "From" header must be included.
- bh=: The base64-encoded hash of the canonicalized message body.
- b=: The base64-encoded signature value computed over the listed headers and the body hash.
Selector Records
DKIM uses selectors to allow a domain to have multiple active key pairs simultaneously. The public key for a selector is published as a DNS TXT record at selector._domainkey.example.com. For example, if the selector is s1 and the domain is example.com, the public key lives at:
s1._domainkey.example.com TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
The TXT record contains:
- v=DKIM1: Identifies this as a DKIM key record.
- k=: The key type (
rsaored25519). - p=: The base64-encoded public key. An empty
p=value means the key has been revoked.
Selectors are useful because they allow different mail systems to sign with different keys. For instance, your primary mail server might use selector s1 while your marketing email platform uses selector mktg. Each service has its own key pair, and if one key is compromised, you can revoke it without affecting the others.
Key Rotation
Key rotation is the practice of periodically replacing DKIM key pairs. Regular rotation limits the window of exposure if a private key is compromised and is considered a security best practice. A recommended rotation schedule is every 6 to 12 months.
The rotation process works as follows:
- Generate a new key pair and publish the new public key in DNS under a new selector (for example, rotate from
s1tos2). - Wait for DNS propagation to ensure the new public key is available worldwide. Allow at least 24-48 hours.
- Update the mail server to sign with the new private key and new selector.
- Keep the old public key in DNS for a transition period (1-2 weeks) so that messages signed with the old key that are still in transit can be verified.
- Remove the old public key from DNS by setting
p=to an empty value, which revokes the old key.
For RSA keys, use a minimum key length of 2048 bits. The older 1024-bit keys are considered weak and can be factored with sufficient computing resources. Ed25519 keys are shorter and faster to verify while providing equivalent or better security.
DKIM Alignment
DMARC requires that the domain in the DKIM signature (d= tag) aligns with the domain in the header "From" address. Alignment can be relaxed (organizational domain match) or strict (exact domain match).
For example, if the "From" address is user@example.com:
- Relaxed alignment passes if
d=example.comord=mail.example.com(same organizational domain). - Strict alignment requires
d=example.comexactly.
Third-party email services sometimes sign messages with their own domain (for example, d=sendgrid.net). This will not align with your domain for DMARC purposes. To achieve DKIM alignment, you need to configure custom DKIM signing with your own domain, which typically involves adding CNAME records that point your selector to the provider's key infrastructure.
Common DKIM Issues
Several issues can cause DKIM verification failures:
- Message modification in transit: Mailing lists, forwarding services, and security gateways that alter message headers or body content will break DKIM signatures. This is a known limitation, and DMARC uses SPF as a fallback in these cases.
- DNS propagation delays: If the public key is not yet available in DNS when the first signed message arrives, verification fails.
- Key size too small: 512-bit and 1024-bit RSA keys are increasingly rejected by receivers. Use 2048-bit RSA or Ed25519.
- Incorrect canonicalization: Using
simple/simplecanonicalization is more likely to fail because it does not tolerate any whitespace changes. Preferrelaxed/relaxed. - Missing headers in the signature: If critical headers like "From", "To", "Subject", and "Date" are not included in the
h=tag, an attacker could modify them without invalidating the signature. - DNS TXT record formatting: Long public keys must be split into multiple strings within the TXT record. Improperly split records will cause lookup failures.
DKIM and DNS
DKIM public keys are stored as DNS TXT records, making DNS configuration a critical part of DKIM deployment. Ensure your DNS provider supports TXT records long enough to hold 2048-bit public keys (which result in approximately 400 characters of base64-encoded data). Some older DNS systems truncate long records, which silently breaks DKIM verification.
DKIM in the Email Authentication Stack
DKIM works alongside SPF and DMARC to provide comprehensive email authentication. SPF validates the sending server's IP address. DKIM validates message integrity and domain ownership through cryptographic signatures. DMARC ties both results together, enforces a policy based on alignment, and provides reporting. Deploying all three is essential for protecting your domain from spoofing, improving deliverability, and meeting the authentication requirements of major mailbox providers.
Summary
DKIM is a critical email security protocol that uses public-key cryptography to verify that email messages are authorized by the domain owner and have not been tampered with. By publishing a public key in DNS and signing outgoing messages with the corresponding private key, DKIM gives receivers a reliable way to validate message authenticity. Combined with SPF and DMARC, DKIM provides robust protection against email-based threats.
Need help securing your infrastructure? Explore NOC.org plans to get started.