DKIM Technical Reference (RFC 6376)
Annotated walkthrough of RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures. How signing works, key record format, canonicalization modes, verification steps, and security guidance from the spec itself.
What This Reference Covers
RFC 6376 defines DomainKeys Identified Mail (DKIM) — a protocol that lets a domain cryptographically sign outgoing email so that receiving servers can verify the message was not altered in transit and was authorized by the signing domain. DKIM is one of the three pillars of email authentication, alongside SPF and DMARC.
This page is an annotated walkthrough of the sections most relevant to email administrators. It is not a replacement for the full RFC — it is a guide to the parts you need to understand when configuring, debugging, or auditing DKIM for your domain.
Use the mxio DKIM Checker to verify your DKIM key records and diagnose signing issues.
How DKIM Signing Works (§3.1)
DKIM uses public-key cryptography. The sending server signs a hash of the message (headers + body) with a private key. The signature is added as a DKIM-Signature header. The receiving server retrieves the corresponding public key from DNS and verifies the signature.
"DKIM separates the question of the identity of the signer of the message from the purported author of the message." — RFC 6376 §1
In practice, this means DKIM proves that the message passed through a specific domain's mail infrastructure and was not modified after signing. It does not prove the From address is legitimate on its own — that is DMARC's job, which checks whether the DKIM signing domain aligns with the From domain.
The Signing Flow
- Sender composes the message (headers + body)
- Sending server canonicalizes the message (normalizes whitespace and formatting per the chosen algorithm)
- Sending server hashes the canonicalized body, then signs a hash of selected headers plus the body hash
- Signature is added as a
DKIM-Signatureheader - Receiving server extracts the
d=(domain) ands=(selector) from the signature, queries DNS for{selector}._domainkey.{domain}, retrieves the public key, and verifies the signature
If verification fails, the message fails DKIM. See DKIM Body Hash Did Not Verify for the most common failure scenario.
The DKIM-Signature Header (§3.5)
Every DKIM-signed message carries a DKIM-Signature header with semicolon-delimited tags. Here is what each tag means:
| Tag | Required | Description |
|---|---|---|
v= |
Yes | Version — always 1 |
a= |
Yes | Signing algorithm — rsa-sha256 (recommended) or rsa-sha1 (deprecated) or ed25519-sha256 |
b= |
Yes | The signature data (base64-encoded) |
bh= |
Yes | Body hash (base64-encoded hash of the canonicalized body) |
c= |
No | Canonicalization algorithm — e.g., relaxed/relaxed. Default: simple/simple |
d= |
Yes | Signing domain — the domain claiming responsibility |
h= |
Yes | Signed headers — colon-separated list of header fields included in the signature |
i= |
No | Agent or User Identifier (AUID) — defaults to @d= value |
l= |
No | Body length limit — number of body bytes signed. Dangerous — see Security section |
q= |
No | Query method — always dns/txt |
s= |
Yes | Selector — identifies which key record to query |
t= |
No | Signature timestamp (Unix epoch) |
x= |
No | Signature expiration (Unix epoch) |
Example
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=selector1;
h=from:to:subject:date:message-id;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk...
This tells the verifier: look up selector1._domainkey.example.com, use rsa-sha256 with relaxed/relaxed canonicalization, and verify the signature covers the from, to, subject, date, and message-id headers plus the body.
The DNS Key Record (§3.6)
The DKIM public key lives in a DNS TXT record at {selector}._domainkey.{domain}. Its format is also semicolon-delimited tags:
| Tag | Required | Description |
|---|---|---|
v= |
No | Version — DKIM1 (recommended but optional per spec) |
k= |
No | Key type — rsa (default) or ed25519 |
p= |
Yes | Public key data (base64-encoded). Empty p= means key is revoked |
h= |
No | Acceptable hash algorithms — sha256 (or sha1, deprecated) |
t= |
No | Flags — y (testing mode), s (strict i= matching) |
s= |
No | Service type — * (all, default) or email |
n= |
No | Notes — human-readable, not machine-parsed |
Key Types (§3.6.1)
RFC 6376 originally defined only rsa. RFC 8463 later added ed25519 (Edwards-curve Digital Signature Algorithm), which offers equivalent security at much smaller key sizes. In practice:
- RSA — universally supported. Use 2048-bit keys minimum (RFC 6376 §3.3.3 recommends 1024 as minimum, but 2048 is the current industry standard). 4096-bit keys may exceed DNS UDP response limits.
- Ed25519 — gaining adoption. Significantly smaller keys and signatures. Not yet supported by all verifiers. Best deployed alongside an RSA signature for compatibility.
Key Revocation
To revoke a DKIM key, publish the record with an empty p= tag:
selector1._domainkey.example.com TXT "v=DKIM1; p="
"If the result of the query is that the public key has been revoked, the verifier SHOULD consider the signature to have failed." — RFC 6376 §6.1.2
This is how you disable a compromised key without removing the DNS record entirely.
If the DKIM Checker reports "No DKIM record found," see DKIM Record Not Found for common causes and fixes.
Hash Algorithms (§3.3)
DKIM supports two hash algorithms for signing:
rsa-sha256— required by all DKIM implementations. Use this.rsa-sha1— deprecated. RFC 8301 formally moved SHA-1 signing to "not recommended" status. Some verifiers still accept it; many modern systems reject or downgrade messages signed with SHA-1.
"Signers MUST NOT use rsa-sha1." — RFC 8301 §3
If the DKIM Checker flags h=sha1 in your key record, you are restricting verifiers to SHA-1. Remove the h= tag (defaulting to all algorithms) or set h=sha256.
Canonicalization (§3.4)
Email messages get modified in transit — mailing lists add footers, forwarders rewrap lines, gateways convert line endings. Canonicalization defines how the signer and verifier normalize the message before hashing, so that minor modifications do not break the signature.
The c= tag specifies two algorithms separated by a slash: header/body.
Simple Canonicalization
- Headers: No changes. Headers must match exactly (case and whitespace).
- Body: Trailing empty lines are ignored. Otherwise, byte-for-byte match.
Simple canonicalization is fragile — any header modification breaks verification.
Relaxed Canonicalization
- Headers: Header names are lowercased. Sequential whitespace is collapsed to a single space. Trailing whitespace is removed.
- Body: Trailing whitespace on each line is removed. Sequential whitespace within lines is collapsed. Trailing empty lines are removed.
Relaxed canonicalization tolerates the whitespace modifications that commonly occur in transit.
Recommendation
Use c=relaxed/relaxed. This is what Google Workspace, Microsoft 365, and most modern providers use. Simple canonicalization breaks too easily on mailing lists and forwarding servers.
Verification (§6.1)
When a receiving server gets a message with a DKIM-Signature header, it:
- Extracts
d=ands=from the signature - Queries DNS for
{s}._domainkey.{d}TXT record - Retrieves the public key from the
p=tag - Canonicalizes the message using the algorithm specified in
c= - Hashes the body and compares to
bh= - Verifies the signature in
b=against the signed headers + body hash using the public key
If any step fails — DNS lookup fails, key is revoked, body hash does not match, signature is invalid — DKIM verification fails.
Signature Expiration (§6.1.1)
The x= tag sets an expiration timestamp. After this time, verifiers may consider the signature invalid:
"Signatures MAY be considered invalid if the verification time at the verifier is past the expiration date." — RFC 6376 §6.1.1
The keyword is "MAY" — verifier behavior varies. Some providers ignore expiration entirely. Do not rely on expiration as a security mechanism; use it as a hygiene signal.
Testing Mode (t=y)
The t=y flag in the DNS key record signals that the domain is testing DKIM and signatures should not be treated as definitive:
"Verifiers MUST NOT treat messages from signers in testing mode differently from unsigned email." — RFC 6376 §3.6.1
In practice, t=y means DKIM failures will not harm your deliverability, but DKIM passes will not help it either. Remove t=y once you have confirmed signing works correctly. The DKIM Checker flags this as a warning.
Key Rotation
RFC 6376 does not mandate key rotation, but §3.6 and §8 strongly imply it through the selector mechanism:
"The selector subdivides the d= namespace to allow multiple keys under the same domain." — RFC 6376 §3.1
The selector system exists specifically to support key rotation without downtime:
- Generate a new key pair with a new selector (e.g.,
selector2) - Publish the new public key in DNS at
selector2._domainkey.example.com - Wait for DNS propagation (TTL of the old record)
- Switch signing to use the new selector
- Revoke the old key by setting
p=to empty, or remove the old DNS record after all in-flight messages have been delivered
How Often to Rotate
RFC 6376 does not specify a rotation interval. Industry practice varies:
- Google Workspace: Rotates automatically
- Microsoft 365: Manual rotation recommended every 6-12 months
- MailRoute: Keys (
mr01,mr02,mr03) are auto-rotated by the service - Best practice: Rotate at least annually, immediately if a key may be compromised, and whenever key size needs upgrading (e.g., 1024-bit → 2048-bit)
Security Considerations (§8)
DKIM Does Not Authenticate the From Address
"DKIM's authentication of the identity of the signer does not, by itself, represent an authorization or endorsement of the content of the message." — RFC 6376 §1
DKIM proves that d=example.com signed the message. It does not prove that the message's From: user@example.com header is legitimate. A phisher could sign a message with their own domain and set the From header to your domain. DMARC alignment solves this by requiring the DKIM d= domain to match the From domain.
The Body Length Limit (l=) Is Dangerous
The l= tag limits how many bytes of the body are included in the hash. Any content after the limit is unsigned and can be modified without breaking the signature:
"Use of the l= tag might allow display of fraudulent content without appropriate warning to the user." — RFC 6376 §8.2
An attacker who intercepts the message can append content — including links, images, or HTML — after the signed portion. The signature still verifies, making the appended content appear legitimate. Do not use l= in production signing.
Key Size Requirements
RFC 6376 §3.3.3 specifies 1024 bits as the minimum RSA key size. However, 1024-bit RSA is considered weak by modern standards. Use 2048-bit keys. Some organizations use 4096-bit, but these can cause DNS response truncation (TXT records exceeding 512 bytes require TCP fallback via EDNS0).
Quick Reference
| What you are checking | RFC section | Tool |
|---|---|---|
| Does the DKIM key record exist? | §3.6 | DKIM Checker |
Is the key revoked (empty p=)? |
§3.6.1 | DKIM Checker |
| What algorithm is used? | §3.3 | DKIM Checker |
Is the key in testing mode (t=y)? |
§3.6.1 | DKIM Checker |
| What canonicalization is configured? | §3.4 | Header Analyzer |
| Does the body hash match? | §6.1 | Header Analyzer |
| Does DKIM align with DMARC? | See RFC 7489 | DMARC Checker |
This reference covers RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures, authored by D. Crocker, T. Hansen, and M. Kucherawy. Supplementary RFCs referenced: RFC 8301 (cryptographic algorithm update), RFC 8463 (Ed25519 key type). Content on this page is an editorial interpretation; see the original RFC for normative text. RFC content is subject to the IETF Trust's Legal Provisions.
Related Articles
No DKIM record found for your domain and selector. Learn how to find your DKIM selector, publish the DNS record, and verify the configuration.
Your DKIM signature is failing with body hash verification errors. Understand why email body modification breaks DKIM and how to fix it.
DMARC authentication is failing for your domain. Understand the most common causes — alignment issues, missing records, third-party senders — and fix them.
SPF and DKIM both pass but DMARC still fails? The problem is alignment. Learn what DMARC alignment means and how to fix relaxed vs strict alignment issues.
Understand how SPF, DKIM, and DMARC work together to protect your domain from spoofing and improve email deliverability. A practical guide for email administrators.
Annotated walkthrough of RFC 7489 — Domain-based Message Authentication, Reporting, and Conformance. Policy tags, alignment, reporting, and security considerations from the spec itself.
A section-by-section walkthrough of RFC 7208, the standard that defines SPF. Covers every mechanism, qualifier, the 10-lookup limit, void lookups, ptr deprecation, macros, and security considerations — with practical examples and tool links.