DEV Community

Cover image for DKIM Explained: How Email Digital Signatures Protect Your Domain
toolbox-poster
toolbox-poster

Posted on • Originally published at toolbox.starnomina.tn

DKIM Explained: How Email Digital Signatures Protect Your Domain

TL;DR
DKIM (DomainKeys Identified Mail) adds a cryptographic signature to every outgoing email, allowing recipients to verify that the message was authorized by the domain owner and was not tampered with in transit. Defined in RFC 6376, DKIM is the most resilient authentication mechanism in the email stack โ€” unlike SPF, it survives forwarding. This guide details the signing architecture, dissects every tag in the DKIM-Signature header, compares RSA and Ed25519 algorithms, and covers key rotation, canonicalization, over-signing, and common failure modes.

๐Ÿ“‘ Table of Contents

  • How DKIM Works
  • DKIM-Signature Header Anatomy
  • The Selector Concept
  • RSA vs Ed25519
  • Canonicalization: Simple vs Relaxed
  • Key Rotation Procedure
  • DKIM + DMARC Alignment
  • Over-Signing
  • Best Practices
  • Common Failures
  • Tools
  • Sources & References

1. How DKIM Works

DKIM uses asymmetric cryptography (public/private key pair) to sign emails. The sending server holds the private key; the public key is published in DNS. When a recipient receives the message, it retrieves the public key and verifies the signature.

Key Generation
The domain owner generates an RSA (or Ed25519) key pair. The private key is installed on the mail server or ESP. The public key is published as a DNS TXT record at selector._domainkey.example.com.

Message Signing
The sending MTA selects headers to sign (e.g., From, To, Subject, Date) and the message body. It canonicalizes them (normalizes whitespace), hashes the result, and encrypts the hash with the private key.

Signature Insertion
The encrypted hash (signature) and metadata are placed in a DKIM-Signature header prepended to the message. This header includes the selector, algorithm, signed headers list, and the base64-encoded signature value.

DNS Lookup
The receiving MTA reads the DKIM-Signature header, extracts the selector (s=) and domain (d=), and queries s._domainkey.d for the public key TXT record.

Verification
The receiver re-canonicalizes the signed headers and body, computes the hash, and uses the public key to decrypt the signature. If the hashes match, the signature is valid โ€” the message is authentic and unmodified.

DMARC Evaluation
If the d= domain aligns with the From: header domain (relaxed or strict), DMARC considers DKIM as a passing authentication result.

๐Ÿ’ก DKIM does not encrypt the message content. It only provides a digital signature that proves origin and integrity. The message itself is still transmitted in cleartext (unless TLS is used at the transport layer).

2. DKIM-Signature Header Anatomy

Every DKIM-signed message contains a DKIM-Signature header with the following tags:

Enter fullscreen mode Exit fullscreen mode
Tag Required Meaning Values
v Yes Version 1 (always)
a Yes Signing algorithm rsa-sha256, rsa-sha1 (deprecated), ed25519-sha256
d Yes Signing domain (DMARC alignment key) e.g., example.com
s Yes Selector (lookup key for public key) e.g., selector1, google, s1
h Yes Signed header fields Colon-separated list of header names
b Yes Signature data (base64) Cryptographic signature value
bh Yes Body hash (base64) Hash of the canonicalized body
c No Canonicalization (header/body) simple/simple (default), relaxed/relaxed, relaxed/simple
t No Signature timestamp (Unix epoch) e.g., 1712880000
x No Signature expiration (Unix epoch) e.g., 1713484800
l No Body length limit (bytes signed) Integer โ€” avoid using
i No Agent or user identifier Must be a subdomain of d=
q No Query method dns/txt (default, only value)
z No Copied header fields (for diagnostics) Pipe-separated copies of signed headers

๐Ÿšซ Never use the l= (body length) tag. It tells verifiers to only check the first N bytes of the body, allowing attackers to append malicious content after the signed portion. RFC 6376 ยง8.2 explicitly warns about this vulnerability.

3. The Selector Concept

A selector is a label that lets a single domain have multiple DKIM keys simultaneously โ€” essential for key rotation and multi-service environments. The public key is published at ._domainkey..

๐Ÿ“– Definition โ€” A DKIM selector is an arbitrary string chosen by the domain owner that identifies a specific public key record in DNS. It is specified in the s= tag of the DKIM-Signature header and used to construct the DNS query: selector._domainkey.domain.com.

Selectors by Provider

Provider Typical Selector(s) DNS Record Location
Google Workspace google google._domainkey.example.com
Microsoft 365 selector1, selector2 selector1._domainkey.example.com
SendGrid s1, s2 s1._domainkey.example.com
Mailchimp k1 k1._domainkey.example.com
Amazon SES Auto-generated (CNAME-based) 3 CNAME records per domain
Postmark 20240101 (date-based) CNAME to Postmark DNS

โšก Pro Tip: Use descriptive selectors that include the date or purpose: google-2024, marketing-q1. This makes key rotation audits much easier โ€” you can tell at a glance which keys are current and which are deprecated.

4. RSA vs Ed25519

RFC 8463 (2018) introduced Ed25519 as an alternative to RSA for DKIM signatures. Here's how they compare:

Property RSA-SHA256 Ed25519-SHA256
RFC RFC 6376 RFC 8463
Key Size 1024โ€“4096 bits (2048 recommended) 256 bits (fixed)
Signature Size ~342 bytes (2048-bit) 88 bytes (fixed)
DNS TXT Record Size ~400 bytes (2048-bit public key) ~60 bytes
Performance Slower signing & verification Significantly faster
Security Secure at 2048+ bits 128-bit equivalent security
Receiver Support Universal Growing (Gmail, Fastmail support it)

๐ŸŽฏ Dual-sign with both RSA-2048 and Ed25519. Receivers that support Ed25519 benefit from smaller signatures and faster verification. Receivers that don't will fall back to the RSA signature. Each signature uses a different selector.

โš ๏ธ 1024-bit RSA keys are deprecated. RFC 8301 (2018) requires a minimum of 2048 bits for RSA DKIM keys. Some receivers (notably Gmail) will reject 1024-bit signatures. Rotate immediately if you're still using 1024-bit keys.

5. Canonicalization: Simple vs Relaxed

Canonicalization normalizes the message before hashing to tolerate minor modifications by intermediate mail servers. The c= tag specifies the algorithm for headers and body separately (e.g., c=relaxed/relaxed).

Mode Headers Body
Simple No changes โ€” headers must be byte-identical Trailing empty lines removed; no other changes
Relaxed Header names lowercased; whitespace folding normalized; trailing whitespace removed Whitespace sequences reduced to single space; trailing whitespace on lines removed; trailing empty lines removed
# simple/simple โ€” very strict, breaks easily:
Subject: Hello World     โ†  exact bytes must match

# relaxed/relaxed โ€” tolerant of whitespace changes:
Subject:Hello World      โ†  extra spaces and case changes are normalized
subject: hello world     โ†  both canonicalize to the same form
Enter fullscreen mode Exit fullscreen mode

โšก Pro Tip: Always use c=relaxed/relaxed. Intermediate servers (mailing lists, forwarding services, antivirus gateways) frequently modify whitespace. Simple canonicalization causes unnecessary DKIM failures in real-world mail flows.

6. Key Rotation Procedure

DKIM keys should be rotated periodically (every 6โ€“12 months) to limit exposure if a private key is compromised. The selector mechanism makes zero-downtime rotation straightforward.

Generate new key pair
Create a new RSA-2048 or Ed25519 key pair with a new selector (e.g., dkim-202604).

Publish new public key
Add the new TXT record at dkim-202604._domainkey.example.com. Wait for DNS propagation (TTL).

Switch signing to new selector
Configure your MTA/ESP to sign outgoing mail with the new private key and selector.

Monitor for failures
Watch DMARC reports and DKIM verification headers for a few days. Ensure the new key passes.

Revoke old key
After the overlap period (1โ€“2 weeks), publish an empty p= tag for the old selector: v=DKIM1; p=. This tells receivers the key is revoked.

Remove old DNS record
After another TTL cycle, delete the old selector's DNS record entirely.

๐Ÿ’ก An empty p= tag in a DKIM DNS record (RFC 6376 ยง3.6.1) is the official revocation signal. It tells verifiers that the key has been deliberately revoked, as opposed to a missing record which could be a DNS failure.

7. DKIM + DMARC Alignment

For DMARC to consider DKIM as a passing result, two conditions must be met:

  1. DKIM signature must verify (valid cryptographic signature).

  2. The d= domain must align with the From: header domain.

Scenario DKIM d= From Header DMARC adkim Aligned?
Exact match example.com user@example.com Any Yes
Subdomain (relaxed) mail.example.com user@example.com r Yes
Subdomain (strict) mail.example.com user@example.com s No
Third-party domain sendgrid.net user@example.com Any No

โš ๏ธ Many ESPs sign with d=esp-domain.com by default. You must configure custom DKIM signing so the d= tag uses your domain (or a subdomain of it in relaxed mode) for DMARC alignment to work.

8. Over-Signing

๐Ÿ“– Definition โ€” Over-signing is a DKIM best practice where the h= tag includes headers that are not present in the message (e.g., listing Reply-To twice). This prevents attackers from adding a spoofed Reply-To header after signing โ€” any addition would invalidate the signature.

# Over-signing example: listing headers that don't exist in the message
h=from:to:subject:date:reply-to:reply-to:cc:cc

# "reply-to" is listed twice:
# First instance covers the actual Reply-To header (if present)
# Second instance "seals" the slot โ€” adding a new Reply-To breaks the signature
Enter fullscreen mode Exit fullscreen mode

๐ŸŽฏ Over-sign these headers at minimum: From, To, Subject, Date, Reply-To, CC, Content-Type, MIME-Version, Message-ID. Over-signing prevents post-signature header injection attacks.

9. Best Practices

Use 2048-bit RSA minimum
1024-bit keys are deprecated (RFC 8301). Generate 2048-bit keys for all selectors.

Use relaxed/relaxed canonicalization
Simple canonicalization fails too easily with intermediate MTAs. Relaxed is the industry standard.

Sign with your domain
Ensure the d= tag matches your From: domain for DMARC alignment. Configure custom DKIM on every ESP.

Rotate keys every 6โ€“12 months
Use the selector system for zero-downtime rotation. Revoke old keys with an empty p= tag.

Over-sign critical headers
List From, Reply-To, Subject, and CC twice in the h= tag to prevent header injection.

Never use the l= tag
Body length limits allow content to be appended to signed messages. Always sign the full body.

10. Common Failures

๐Ÿšซ DNS record not found. The most common DKIM failure. Usually caused by a typo in the selector name, missing CNAME, or DNS propagation delay. Always verify with dig TXT selector._domainkey.example.com.

๐Ÿšซ Body hash mismatch (bh= tag). The body was modified after signing โ€” typically by a mailing list, antivirus gateway, or footer-appending service. Use relaxed body canonicalization and investigate the specific MTAs in the delivery chain.

โš ๏ธ Key too short. 512-bit and 1024-bit RSA keys are rejected by many receivers. Gmail logs dkim=neutral (body hash did not verify) for weak keys even when the signature is mathematically valid.

โš ๏ธ Expired signature. If the x= tag is set and the current time exceeds it, the signature is treated as invalid. Use generous expiration windows (7+ days) or omit x= entirely.

โš ๏ธ Testing with email headers. To debug DKIM, view the full message headers and look for Authentication-Results. Gmail shows dkim=pass, dkim=fail, or dkim=neutral with a reason string.

Enter fullscreen mode Exit fullscreen mode

11. Tools

Tool Purpose
DKIM Record Checker Look up any selector's public key and validate record syntax

12. Sources & References

  • ๐Ÿ“„ RFC 6376 โ€” DomainKeys Identified Mail (DKIM) Signatures

  • ๐Ÿ“„ RFC 8463 โ€” A New Cryptographic Signature Method for DKIM (Ed25519-SHA256)

  • ๐Ÿ“„ RFC 8301 โ€” Cryptographic Algorithm and Key Usage Update to DKIM

  • ๐Ÿ“„ RFC 7489 โ€” DMARC

  • ๐Ÿ“„ Google Workspace โ€” Turn on DKIM signing

  • ๐Ÿ“„ Microsoft 365 โ€” Use DKIM to validate outbound email

  • ๐Ÿ“„ Cloudflare โ€” What is a DKIM record?

  • ๐Ÿ“„ M3AAWG โ€” Best Practices (includes DKIM guidance)

๐ŸŽฏ Key Takeaway: DKIM is the most durable email authentication mechanism โ€” it survives forwarding, validates message integrity, and provides the preferred alignment path for DMARC. Use 2048-bit RSA or Ed25519, always choose relaxed/relaxed canonicalization, sign with your own domain for DMARC alignment, over-sign critical headers, rotate keys every 6โ€“12 months, and never use the l= body length tag.


Originally published on StarNomina ToolBox. Try our free online tools โ€” no signup required.

Top comments (0)