DKIM Explained: How Email Signatures Prevent Spoofing
What Is DKIM?
DomainKeys Identified Mail (DKIM) is an email authentication protocol that lets the sending server attach a digital signature to every outgoing message. The receiving server uses a public key published in DNS to verify that the message was actually sent by the claimed domain and wasn't tampered with in transit.
If SPF answers "was the sending server authorized?", DKIM answers "was this message actually sent by the domain it claims and was it modified along the way?"
How DKIM Works
1. Key Generation
The domain owner generates an RSA or Ed25519 key pair:
- Private key: Kept secret on the mail server. Used to sign outgoing messages.
- Public key: Published in DNS as a TXT record. Used by receivers to verify signatures.
2. Signing
When an email is sent, the mail server:
- Selects specific headers to sign (typically
From,To,Subject,Date,MIME-Version, etc.) - Canonicalizes the headers and body (normalizes formatting to prevent false failures)
- Computes a hash of the body
- Creates a signature over the selected headers + body hash using the private key
- Adds a
DKIM-Signatureheader to the message
3. Verification
When the receiving server gets the message:
- Extracts the
DKIM-Signatureheader - Looks up the public key via DNS:
{selector}._domainkey.{domain} - Verifies the signature using the public key
- Checks that the body hash matches
- Records the result in the
Authentication-Resultsheader
The DKIM-Signature Header
Here's what a real DKIM signature looks like:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=google;
h=from:to:subject:date:mime-version;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk...
| Tag | Meaning |
|---|---|
v=1 |
DKIM version |
a=rsa-sha256 |
Signing algorithm |
c=relaxed/relaxed |
Canonicalization (header/body) |
d=example.com |
Signing domain |
s=google |
Selector (identifies which key to use) |
h=from:to:... |
Headers included in the signature |
bh=... |
Body hash |
b=... |
The signature itself |
Selectors
A single domain can have multiple DKIM keys, each identified by a selector. This enables:
- Key rotation without downtime — publish the new key with a new selector before retiring the old one
- Multiple signing services — Google Workspace uses
google, SendGrid usess1, etc.
The DNS lookup format is: {selector}._domainkey.{domain}
For example, google._domainkey.example.com returns the DKIM public key used by Google Workspace for example.com.
Canonicalization
Email passes through many servers, and each one can subtly modify the message (adding headers, adjusting whitespace, wrapping lines). Canonicalization normalizes the message before signing/verifying to prevent false failures.
Two modes:
- Simple: Almost no modifications tolerated. Headers and body must match exactly.
- Relaxed: Tolerates common modifications — extra whitespace, header name case changes, trailing whitespace.
Most services use c=relaxed/relaxed (relaxed for both headers and body), which is the most forgiving.
DKIM Alignment and DMARC
DKIM on its own proves that a message was signed by a particular domain. But DMARC adds alignment — it checks whether the DKIM signing domain (d=) matches the From header domain.
Strict alignment: d=example.com must exactly match the From domain.
Relaxed alignment: d=mail.example.com aligns with a From address of user@example.com (organizational match).
This alignment is what prevents an attacker from signing with their own DKIM key — the signature would be valid, but it wouldn't align with the spoofed From domain.
Common DKIM Issues
Missing DKIM Record
If the selector's DNS record doesn't exist, verification fails immediately. Always verify your DKIM records are published after setting up a new service.
Key Too Short
RSA keys shorter than 1024 bits are considered insecure and may be rejected by receivers. Use 2048-bit keys when possible.
Body Modification by Intermediaries
Mailing lists, forwarding services, and security gateways can modify the message body, breaking the DKIM signature. The l= (body length) tag can help in some cases, but it introduces security trade-offs.
Expired Signatures
The optional x= tag sets a signature expiration. If present and expired, the signature fails verification. This is rarely used in practice.
CNAME Selectors
Some email providers (particularly Microsoft 365) use CNAME records for DKIM selectors instead of TXT records. The CNAME points to the provider's DKIM key, which they can rotate without requiring DNS changes from you.
Setting Up DKIM
Step 1: Generate Keys
Most email providers handle this for you. For Google Workspace, it's in Admin Console → Apps → Google Workspace → Gmail → Authenticate email. For Microsoft 365, it's in the Defender portal under Email authentication.
Step 2: Publish the Public Key
Add a TXT record (or CNAME) to your DNS:
Hostname: google._domainkey.example.com
Type: TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqh...
Step 3: Enable Signing
Turn on DKIM signing in your email provider's settings. For some providers this is automatic once the DNS record is published.
Step 4: Verify
Send a test email and check the Authentication-Results header for dkim=pass. Use a DKIM checker tool to verify the DNS record is correct.
Key Rotation
DKIM keys should be rotated periodically (annually at minimum) to limit the impact of key compromise:
- Generate a new key pair with a new selector
- Publish the new public key in DNS
- Wait for DNS propagation (24–48 hours)
- Switch your mail server to sign with the new key
- Keep the old DNS record for a few days (messages in transit may still need it)
- Remove the old DNS record
DKIM vs SPF
| Aspect | SPF | DKIM |
|---|---|---|
| What it checks | Sending server IP | Message integrity + sender |
| Survives forwarding | No | Usually yes |
| DNS record type | TXT on domain | TXT on selector subdomain |
| Limit | 10 DNS lookups | No lookup limit |
| Protects against | Unauthorized servers | Tampering + impersonation |
Both are needed. SPF catches unauthorized servers. DKIM catches tampering and survives forwarding. Together with DMARC, they form a complete authentication framework.
Best Practices
- Use 2048-bit RSA keys (or Ed25519 if your provider supports it)
- Sign all important headers:
From,To,Subject,Date,MIME-Version,Content-Type - Use relaxed canonicalization:
c=relaxed/relaxedprevents false failures - Rotate keys annually: Limit exposure from potential key compromise
- Monitor DMARC reports: They tell you when DKIM failures occur and from which sources
- Set up DKIM for every sending service: Third-party tools (CRMs, ticketing systems, marketing platforms) all need their own DKIM configuration