emailmarketing.net

DKIM (DomainKeys Identified Mail)

RFC 6376 reference plus RFC 8301 (rsa-sha256 required, 1024–4096-bit keys) and RFC 8463 (ed25519-sha256) — signature and key record syntax, tag meanings, canonicalization, signing scope, and risks.

Referenceesp-operatorsender

DKIM (RFC 6376) is a content-based authentication protocol: a domain takes responsibility for a message by adding a DKIM-Signature header containing cryptographic hashes of selected headers and the body, verifiable against a public key published in DNS. A validating signature proves the signed content was not altered after signing and ties the message to the d= domain — the identifier DMARC aligns against (see DMARC). Unlike SPF, DKIM survives forwarding as long as the signed content isn't modified.

The DKIM-Signature header — tag reference

Tag Req? Meaning
v= Required Version; must be 1.
a= Required Signing algorithm: rsa-sha256 or ed25519-sha256 (RFC 8463). rsa-sha1 MUST NOT be used (RFC 8301).
b= Required The signature itself, base64. Whitespace ignored.
bh= Required Hash of the canonicalized body (limited by l= if present), base64.
c= Optional Canonicalization as header/body; each is simple or relaxed. Default simple/simple; c=relaxed alone means relaxed/simple.
d= Required SDID — the signing domain claiming responsibility; must have a key record in DNS. This is the DMARC alignment identifier.
h= Required Colon-separated, ordered list of signed header fields. Must not be empty and must not include the DKIM-Signature being created. May list the same name multiple times and may list nonexistent fields (see oversigning below).
i= Optional AUID — agent/user identity, an address whose domain must equal or be a subdomain of d= (exactly equal if the key record has flag t=s). Default: @ + the d= value.
l= Optional Body length count: number of canonicalized body octets covered by bh=. Default: entire body. Security risk — see below.
q= Optional Key retrieval method; only dns/txt is defined (default).
s= Required Selector — names the key within the domain (see key record below).
t= Recommended Signature timestamp, Unix seconds. Verifiers may ignore signatures with future timestamps.
x= Recommended Absolute expiration timestamp; must be > t=. Not an anti-replay defense.
z= Optional Diagnostic copy of selected header fields at signing time, `

Signing scope: which headers to sign

  • The From: field MUST be signed (it is the identity DKIM exists to protect and the field DMARC evaluates). In practice also sign Subject, Date, To, Reply-To, Message-ID, MIME headers, and List-* fields.
  • Oversigning: listing a header name in h= one more time than it occurs signs a "null" instance, so any later addition of that header (e.g., a second From: or Subject: injected downstream) breaks the signature. Recommended for From, Subject, To, Reply-To.
  • Multiple instances of a header are signed bottom-up; you cannot selectively sign one instance.

The l= body-length risk

l= lets a signature cover only the first N body octets so intermediaries can append content (e.g., list footers) without breaking it. This means anything appended after N octets is unverified — an attacker can replay a signed message with malicious content appended and the signature still validates. This was exploited in practice ("DKIM l= vulnerability", 2024). Do not sign with l=; verifiers should treat l= signatures with suspicion or ignore the tag's exemption.

The DNS key record

Published as a TXT record at:

<selector>._domainkey.<domain>
Tag Default Meaning
v= DKIM1 Version; if present, must be first tag.
p= — (required) The public key, base64. An empty p= means the key is revoked.
k= rsa Key type: rsa or ed25519 (RFC 8463).
h= all allowed Colon-separated acceptable hash algorithms (sha256; sha1 obsolete).
s= * Service type: * or email.
t= none Flags: y = testing mode; s = the i= domain must exactly equal d= (no subdomain AUIDs).
n= empty Human-readable notes for administrators.

Example (Ed25519, from RFC 8463):

brisbane._domainkey.football.example.com. IN TXT
  "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="

Selector hygiene: selectors allow multiple concurrent keys (per system, per ESP, per date). Rotate keys by publishing a new selector, switching signing, then revoking the old key. Never re-use a selector with a new key — you lose the ability to distinguish legitimately-signed old mail from forgeries.

Algorithms and key sizes (RFC 8301, RFC 8463)

Rule Requirement
Signing algorithm Signers MUST sign with rsa-sha256. rsa-sha1 MUST NOT be used for signing or verifying (SHA-1 is historic).
RSA key size — signers MUST use ≥ 1024-bit keys; 2048-bit recommended (current operational baseline).
RSA key size — verifiers MUST validate keys from 1024 to 4096 bits; MAY support larger. MUST NOT treat signatures made with keys < 1024 bits as valid.
Ed25519 (RFC 8463) a=ed25519-sha256, key record k=ed25519, p= is the base64 Ed25519 public key. Keys are 256 bits → the encoded key is only 44 octets, fitting one 255-byte TXT string (large RSA keys often need split strings).
Dual signing For compatibility, sign with both rsa-sha256 and ed25519-sha256 using different selectors (one key record per selector). Verifier support for Ed25519 is still not universal.

Canonicalization

Canonicalization normalizes content before hashing to tolerate in-transit rewriting; it does not alter the transmitted message.

Algorithm Rules
simple (header) Headers presented exactly as they appear — any change breaks the signature.
relaxed (header) Lowercase header names; unfold continuation lines; collapse whitespace runs to a single space; strip trailing whitespace; remove whitespace around the colon.
simple (body) Strip trailing empty lines; ensure body ends with a single CRLF.
relaxed (body) Strip end-of-line whitespace; collapse internal whitespace runs to a single space; strip trailing empty lines; ensure final CRLF.

relaxed/relaxed is the practical defaultsimple header canonicalization breaks whenever any MTA re-folds or re-wraps headers.

Verification behavior

  • Outcomes per signature: SUCCESS, PERMFAIL (unrecoverable — bad signature, revoked/undersized key, syntax error), TEMPFAIL (transient — e.g., DNS timeout).
  • A failed signature is treated as if the message were unsigned — DKIM failure is not itself grounds for rejection; it simply provides no positive identifier. (DMARC is what turns "no aligned pass" into policy.)
  • Multiple signatures are evaluated independently on their own merits; verifiers keep checking until one verifies. A message can legitimately carry signatures from the author domain and one or more intermediaries.
  • Verifier output must include the d= domain and result — surfaced downstream in the Authentication-Results header.

Deliverability notes

  • Mailbox providers increasingly key reputation to the DKIM d= domain, and favor DKIM over SPF for DMARC alignment, feedback-loop enrollment, and sender tooling.
  • Gmail/Yahoo bulk-sender requirements effectively make an aligned DKIM signature with a ≥1024-bit key (2048 recommended) mandatory at scale.
  • DKIM does not prevent replay: a spammer can resend a legitimately signed message verbatim to new recipients and the signature still passes, spending the d= domain's reputation. Mitigations: short x= expirations, per-recipient/stream selectors, and monitoring.

Related

  • SPF — the path-based counterpart
  • DMARC — alignment and policy on top of DKIM/SPF
  • ARC — chain-of-custody when intermediaries break signatures
#authentication#dkim#dns#rfc6376#rfc8301#rfc8463#ed25519#canonicalization#selectors