DKIM Cryptography Basics: RSA, Ed25519, SHA-256, Canonicalization (RFC 6376 + RFC 8301 + RFC 8463)
A foundational deep dive on the cryptographic primitives under DomainKeys Identified Mail (DKIM): what asymmetric (public-key) cryptography IS in plain language, how RSA signing (rsa-sha256) and Ed25519 signing (ed25519-sha256, RFC 8463) work in the DKIM context, the SHA-256 hash function and why the older rsa-sha1 was deprecated by RFC 8301 (2018) following the 2017 SHAttered collision demonstration, the five-step DKIM signing workflow (canonicalize body, compute body hash, build signed-headers blob, sign with private key, base64 encode), the five-step verification workflow at the receiver, the cryptographic role of canonicalization (relaxed/relaxed is the default and tolerates legitimate transit modifications), RSA key sizes and the 1024-bit deprecation under RFC 8301 + NIST SP 800-57 part 3, the DNS TXT key-publication format and the 255-byte character-string limit (RFC 1035 section 3.3.14) that forces 2048-bit RSA keys to be split across multiple strings, best practices, common mistakes, and an FAQ for the questions operators ask most often when they need to understand the cryptography under DKIM.
This reference is provided in English. DKIM is specified in an English-language RFC (RFC 6376) and the canonical cryptographic vocabulary (RSA, Ed25519, SHA-256, private key, public key, body hash, signed headers, canonicalization, selector) does not translate. We keep the body in the source language so technical terms remain consistent with the specifications.
TL;DR
- DKIM cryptography is the public-key (asymmetric) digital-signature scheme defined by RFC 6376 that binds a signing identity to the body and selected headers of an email message. The signer holds a private key; the public key is published in DNS under a selector-scoped TXT record.
- The default signing algorithm
is
rsa-sha256: RSA digital signatures over a SHA-256 hash. RFC 8301 (2018) prohibits the olderrsa-sha1as cryptographically broken following the SHAttered SHA-1 collision demonstration. - Ed25519 (RFC 8463) is the modern alternative signing algorithm: shorter keys (32-byte public key versus 256-byte RSA-2048), faster signing and verification, no 255-byte TXT-segment splitting, strong cryptographic margins. The canonical dual-algorithm deployment publishes both an RSA-2048 selector and an Ed25519 selector.
- Key size minimums: RFC 8301 requires at least 1024-bit RSA and recommends 2048-bit RSA. NIST SP 800-57 part 3 deprecates 1024-bit RSA for new signing keys. Modern operators publish 2048-bit RSA or Ed25519 public keys.
- The DKIM signing workflow has
five steps: (1) canonicalize the body, (2)
compute a SHA-256 body hash and base64-encode
into the
bh=tag, (3) build the signed-headers blob in canonicalized form, (4) sign the SHA-256 hash of the blob with the private key, (5) base64-encode the signature into theb=tag. - Canonicalization (relaxed- relaxed is recommended) tolerates whitespace normalisation and header refolding so legitimate transit modifications by intermediate MTAs do not invalidate the body hash or the signed-headers hash. Without canonicalization, DKIM would fail on virtually every message.
- A 2048-bit RSA public key does not fit in a single 255-byte DNS TXT character-string (RFC 1035 §3.3.14) and is split across multiple strings within one TXT record. The receiver concatenates them transparently. Ed25519 public keys (44 bytes base64-encoded) avoid the issue.
- DKIM cryptography defends against unauthenticated forgery and in-transit body modification. It does NOT defend against replay (see DKIM replay attacks) or against compromise of the signing private key (mitigated by key rotation — see DKIM key rotation).
1. Overview: what DKIM cryptography is and why it matters
DomainKeys Identified Mail (DKIM) is one of the three pillars of modern email authentication (alongside SPF and the DMARC policy layer built on top of them). DKIM works by attaching a cryptographic signature to every outgoing message and publishing the corresponding verification public key in DNS, so any receiver in the world can independently verify that the message body and selected headers have not been modified in transit and that the signing identity really did sign the message.
The cryptographic primitives DKIM relies on are well-studied: RSA (Rivest-Shamir-Adleman, 1977) for digital signatures over a SHA-256 hash, or the more modern Ed25519 (Bernstein et al., 2011) elliptic-curve digital signature scheme defined for DKIM by RFC 8463. The signing operation is standard public-key cryptography: a private key held by the sender produces a signature; a public key published in DNS lets anyone verify the signature. What DKIM contributes on top of the primitives is the canonicalization layer (so the signature survives legitimate transit modifications by intermediate MTAs) and the DNS publication format (so a receiver can locate the public key by domain and selector).
This page is the foundational cryptographic reference for the DKIM cluster. For DKIM DNS syntax, selectors, and deployment, see the pillar at DKIM explained. For the operational rotation procedure, see DKIM key rotation. For the security-research analysis of replay attacks (which DKIM by design does not prevent), see DKIM replay attacks. This page focuses on the cryptographic primitives themselves: what asymmetric cryptography is, how RSA and Ed25519 work in the DKIM context, what SHA-256 contributes, the five-step signing workflow, the five-step verification workflow, and the key-size and publication-format details that come up in real-world DKIM deployments.
2. Asymmetric (public-key) cryptography in plain language
Asymmetric cryptography (also called public-key cryptography) is a class of cryptographic algorithms that use two mathematically related keys instead of one. The two keys form a keypair: a private key that must be kept secret by its owner, and a public key that can be freely distributed. The mathematical relationship between the two keys is constructed so that:
- Anyone with the public key can verify a signature produced by the corresponding private key.
- Only the holder of the private key can produce a signature that verifies under the public key.
- Knowing the public key does not give an attacker the ability to derive the private key (this is the load-bearing assumption: it relies on the computational hardness of either integer factorisation for RSA or the elliptic-curve discrete-logarithm problem for Ed25519).
DKIM uses asymmetric cryptography in the
digital-signature mode (not the
encryption mode). The signing domain holds the
private key on its mail-sending infrastructure
and uses it to sign every outgoing message; the
public key is published in DNS under a
selector-scoped TXT record at
selector._domainkey.example.com so
every receiver in the world can verify the
signature without needing to negotiate a shared
secret with the sender.
The reason DKIM uses asymmetric cryptography rather than a shared-secret HMAC scheme is scalability. Email exchanges between any two domains; a shared-secret scheme would require every sending domain to negotiate and exchange a secret with every receiving domain in the world, which does not scale to internet email. Public key cryptography lets the sender publish its verification key once in DNS, and every receiver in the world can independently locate it.
3. RSA in DKIM (rsa-sha256)
RSA (Rivest-Shamir-Adleman, 1977) is the historically dominant public-key signature algorithm and the default DKIM signing algorithm per RFC 6376 and RFC 8301. An RSA keypair is generated by selecting two large prime numbers, computing their product (the modulus), and deriving a related private exponent and public exponent. The security of RSA rests on the computational hardness of factoring the modulus back into its prime factors: a 2048-bit modulus is currently believed to require approximately 2^112 operations to factor with the best-known classical algorithms, placing it well beyond the reach of any foreseeable computing resource.
The DKIM signing algorithm name
rsa-sha256 denotes the combination
of RSA signature generation over a SHA-256 hash
of the canonicalized signed-headers blob. The
older rsa-sha1 algorithm is
deprecated by RFC 8301 because the SHA-1 hash
function was demonstrated to admit practical
collisions in 2017 (Stevens et al., the
"SHAttered" attack). Modern DKIM signers MUST
use rsa-sha256; receivers SHOULD
reject rsa-sha1 signatures.
The a= tag in the DKIM-Signature header declares the algorithm. A modern conforming signature looks like:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=mail2026; t=1747843200;
h=From:To:Subject:Date:Message-ID;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=Z8sLqp...base64encoded2048bitRSAsignature...sKf3Q==
The k= tag in the DNS TXT record
declares the matching key type
(k=rsa). A 2048-bit RSA public key
base64-encoded is approximately 392 characters,
which does not fit in a single 255-byte DNS TXT
character-string (see
section 11).
4. Ed25519 in DKIM (ed25519-sha256, RFC 8463)
Ed25519 (Bernstein, Duif, Lange, Schwabe, Yang, 2011) is a modern elliptic-curve digital signature algorithm defined for DKIM by RFC 8463. Ed25519 signatures are built on the Curve25519 elliptic curve and rely on the computational hardness of the elliptic-curve discrete-logarithm problem (ECDLP), which is fundamentally different from the integer-factorisation problem underlying RSA.
The practical advantages of Ed25519 over RSA-2048 for DKIM are:
- Smaller public keys: 32 bytes raw, 44 bytes base64-encoded. An Ed25519 DKIM public-key TXT record fits comfortably in a single DNS character-string with no splitting.
- Smaller signatures: 64 bytes
raw, 88 bytes base64-encoded in the
b=tag — versus approximately 344 base64 characters for RSA-2048. - Faster signing and verification: Ed25519 signing is roughly 10x faster than RSA-2048 signing on commodity hardware; verification is roughly 2x faster.
- Strong cryptographic margins: Ed25519 provides approximately 128-bit security against the best-known classical attacks, comparable to RSA-3072 in security margin but with much smaller keys.
The DKIM signing algorithm name
ed25519-sha256 denotes Ed25519
signature generation over a SHA-256 hash. A
conforming Ed25519 DKIM signature looks like:
DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed;
d=example.com; s=ed2026; t=1747843200;
h=From:To:Subject:Date:Message-ID;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=Z8sLqp...base64encoded64byteEd25519signature==
The DNS TXT record uses
k=ed25519 to declare the key type.
The practical caveat is receiver-side support:
RFC 8463 was published in 2018 and major
receivers (Gmail, Microsoft, Yahoo, Apple)
support Ed25519 verification, but smaller MTAs
and self-hosted Postfix or Exim deployments may
not. The canonical safe deployment publishes
BOTH an RSA-2048 selector AND an Ed25519
selector and signs each outgoing message with
both signatures; receivers verify whichever they
support, and the message passes DKIM if either
signature verifies (RFC 8463 section 5).
5. The SHA-256 hash function in DKIM
SHA-256 is the cryptographic hash function used
by both rsa-sha256 and
ed25519-sha256 to produce a
fixed-length 256-bit (32-byte) digest of the
canonicalized body and of the canonicalized
signed-headers blob. SHA-256 was standardised by
NIST in FIPS 180-2 (2002) and is one of the
SHA-2 family of hash functions, distinct from
the older and now-broken SHA-1.
DKIM uses the SHA-256 hash for two distinct purposes:
- Body hash: the SHA-256
digest of the canonicalized body is
base64-encoded into the
bh=tag of the DKIM-Signature header. The body hash gives DKIM verifiers a way to confirm the message body has not been modified in transit. - Signed-headers hash: the
SHA-256 digest of the canonicalized
signed-headers blob (including the DKIM-Signature
header itself with an empty
b=placeholder) is the input the RSA or Ed25519 signature is actually computed over. The signature does NOT sign the body directly — it signs the hash of the signed-headers blob, which itself contains the body hash.
The two-level structure (body hash inside signed-headers hash inside signature) is the cryptographic chain that gives DKIM its security properties: a modification to any byte of the canonicalized body changes the body hash; a different body hash changes the signed-headers blob; a different signed-headers blob changes the SHA-256 hash the signature was computed over; the signature no longer verifies. Each link in the chain is cryptographically strong (SHA-256 is collision-resistant; RSA-2048 and Ed25519 signatures are forgery-resistant under the standard hardness assumptions).
The older rsa-sha1 algorithm
deprecated by RFC 8301 used SHA-1 (160-bit
digest) instead of SHA-256. SHA-1 was
demonstrated to admit practical collisions in
2017 (the SHAttered attack by Stevens, Bursztein,
Karpman, Albertini, and Markov), and theoretical
work going back to 2005 had already weakened
SHA-1 below the security margins required for
digital signatures. Modern DKIM signers MUST
use SHA-256.
6. The five-step DKIM signing operation
A DKIM signer (typically the outbound MTA or a library inside an application sending mail) follows a fixed five-step sequence to produce a DKIM-Signature header for an outgoing message. Understanding this sequence is essential for debugging DKIM verification failures.
- Step 1: Canonicalize the body. Apply the body canonicalization algorithm (simple or relaxed; relaxed is recommended). Relaxed-body strips trailing whitespace from each line, collapses multiple internal whitespace runs to a single space, and removes empty trailing lines. Simple-body strips only trailing empty lines after the last non-empty line.
- Step 2: Compute the body hash.
Compute the SHA-256 hash of the canonicalized
body and base64-encode the 32-byte digest
into a 44-character string. Place this
string in the
bh=tag of the DKIM-Signature header that is being constructed. - Step 3: Build the signed-headers blob.
Assemble the headers listed in the
h=tag (typically From, To, Subject, Date, Message-ID, Reply-To, plus any others the sender chooses to bind to the signature) in the order they appear in the message, in their canonicalized form (relaxed-headers lowercases header names, unfolds folded lines, and strips trailing whitespace from values). Append the DKIM-Signature header itself with an emptyb=tag placeholder. The concatenation is the signed-headers blob. - Step 4: Sign the signed-headers blob. Compute the SHA-256 hash of the signed-headers blob. Apply the configured signing algorithm (RSA private-key sign, producing an approximately 256-byte signature for RSA-2048; or Ed25519 private-key sign, producing a 64-byte signature). The signing operation is a single private-key operation on the 32-byte SHA-256 hash; the body itself is not passed to the signing operation.
- Step 5: Base64-encode the signature.
Base64-encode the raw signature bytes (344
characters for RSA-2048; 88 characters for
Ed25519) and replace the placeholder
b=tag value with the encoded signature. The completed DKIM-Signature header is now attached to the outgoing message before transmission.
The signing operation is deterministic for a given (message, private key, algorithm, canonicalization) tuple in the case of RSA (PKCS#1 v1.5 deterministic padding) and in the case of Ed25519 (which is deterministic by construction). The same message signed twice with the same key produces the same signature.
7. The five-step DKIM verification operation
A DKIM verifier (typically the inbound MTA or an anti-abuse library at the receiver) follows the same five steps in reverse to validate a DKIM-Signature header on an incoming message:
- Step 1: Parse the DKIM-Signature header.
Extract the tags:
v=(version, always 1),a=(algorithm),c=(canonicalization pair),d=(signing domain),s=(selector),h=(signed headers list),bh=(body hash),b=(signature),t=(timestamp),x=(expiry, if present). - Step 2: Fetch the public key from DNS.
Look up the TXT record at
{selector}._domainkey.{d-value}(for examplemail2026._domainkey.example.com). Parse the returned TXT body for thev=DKIM1; k=rsa; h=sha256; p=<base64-encoded-public-key>tags. Base64-decode the public-key bytes. If the record is missing, malformed, or revoked (p=empty), DKIM verification fails withdkim=noneordkim=permerror. - Step 3: Recompute the body hash.
Apply the body canonicalization algorithm
declared in the
c=tag to the received body. Compute the SHA-256 hash of the canonicalized body. Base64-encode the 32-byte digest. Compare against thebh=value in the DKIM-Signature header. If the values differ, DKIM verification fails withbody-hash-mismatch. - Step 4: Reconstruct the signed-headers blob.
Assemble the canonicalized headers in the
order listed in the
h=tag, followed by the DKIM-Signature header itself with an emptyb=tag placeholder (theb=value in the received header is replaced with the empty string for hashing purposes). Compute the SHA-256 hash of the assembled blob. - Step 5: Verify the signature.
Base64-decode the
b=value into raw signature bytes. Apply the public-key verification operation appropriate to the algorithm declared in thea=tag (RSA-2048 verify, or Ed25519 verify) using the public key fetched in step 2 and the SHA-256 hash computed in step 4. If verification succeeds, the signature is valid and the message has not been modified in transit. If verification fails, DKIM verification fails withdkim=fail.
A passing DKIM verification result is what the
DMARC
alignment layer requires: DMARC checks that
the d= value of the passing DKIM
signature aligns with the
From: header domain (strictly or
relaxed per the adkim= DMARC tag).
DKIM verification with a non-aligned
d= is still a passing DKIM result
but does not contribute to DMARC alignment.
8. Canonicalization and why it matters cryptographically
Canonicalization is the normalisation step that prepares the message body and signed headers for hashing. Without canonicalization, the body hash and the signed-headers hash would be invalidated by virtually any transit modification: trailing whitespace stripping by an intermediate MTA, header refolding by a mailing-list server, character-case changes in a header field name, or any of a dozen other benign modifications that internet email routinely applies.
RFC 6376 defines two body canonicalization
algorithms and two header canonicalization
algorithms; the c= tag declares
which pair the signer chose, in the form
c=header/body:
- simple/simple: minimal normalisation. Headers passed through verbatim; body trailing empty lines stripped. Brittle in practice — many legitimate transits break this.
- relaxed/relaxed (recommended): relaxed-headers lowercases the header name, unfolds folded lines, strips trailing whitespace from the header value, and collapses internal whitespace runs in the value to a single space; relaxed-body strips trailing whitespace from each line, collapses internal whitespace runs to a single space, and removes empty trailing lines. Survives the vast majority of legitimate transit modifications.
- simple/relaxed and relaxed/simple: the two mixed combinations are permitted but rarely used in practice.
The cryptographic significance of canonicalization
is that it defines the input bytes the
signature is computed over. The signer and the
verifier MUST apply identical canonicalization
rules; otherwise the recomputed hash at the
verifier will not match the one computed at the
signer, and verification will fail even though
the underlying content is logically unchanged.
The c= tag in the DKIM-Signature
header is the explicit synchronisation
mechanism: it tells the verifier exactly which
canonicalization pair to apply.
Common signer-side mistakes (covered in
section 13) include
omitting the c= tag (which defaults
to simple/simple, a strict
canonicalization that breaks easily) and
forgetting that the signed-headers blob during
verification includes the DKIM-Signature
header itself with an empty b=
placeholder — not the literal received header
string.
9. RSA key sizes and the 1024-bit deprecation
RFC 8301 (Cryptographic Algorithm and Key Usage Update to DKIM, 2018) updated RFC 6376 with current cryptographic guidance. The relevant requirements are:
- Minimum RSA key size: 1024 bits for verification, 2048 bits recommended for signing. Signers MUST publish keys at least 1024 bits long and SHOULD publish keys of at least 2048 bits.
- Maximum RSA key size: RFC 8301 caps RSA verification keys at 4096 bits (some receivers may reject larger keys because the DNS encoding becomes unwieldy).
- Required hash: SHA-256. SHA-1 is prohibited (deprecated post-SHAttered).
- Required canonicalization: no requirement, but relaxed/relaxed is the de-facto standard.
The practical guidance from NIST SP 800-57 part 3 (Application-Specific Key Management Guidance, 2015 / 2020) deprecates 1024-bit RSA for new signing keys: NIST projects that 1024-bit RSA may become factorable by nation-state-scale resources in the late 2020s. Operators publishing new DKIM signing keys in 2026 should use 2048-bit RSA at minimum; 3072-bit RSA is a reasonable conservative choice for high-value senders; Ed25519 (RFC 8463) is the modern cryptographic alternative.
The base64-encoded DKIM public-key sizes are approximately:
- RSA-1024: 216 characters base64 — fits in a single 255-byte DNS TXT character-string.
- RSA-2048: 392 characters base64 — does NOT fit in a single character-string, must be split.
- RSA-3072: 564 characters base64 — must be split into 3+ strings.
- RSA-4096: 736 characters base64 — must be split into 3+ strings.
- Ed25519: 44 characters base64 — fits comfortably in one string.
10. DNS TXT record key-publication format
The DKIM public key is published as a TXT
record at the name
{selector}._domainkey.{signing-domain}.
The TXT body is a semicolon-delimited list of
tag=value pairs. The defined tags per RFC 6376
section 3.6 are:
v=DKIM1— version, RECOMMENDED (defaults toDKIM1if absent).k=rsaork=ed25519— key algorithm. Defaults torsaif absent.h=sha256— hash algorithm. Defaults to allow any supported hash if absent; modern keys SHOULD declareh=sha256per RFC 8301.s=email— service type. Defaults to*(all). Theemailvalue scopes the key to email signing.n=...— notes, free-form. Not cryptographically significant.p=<base64-encoded-public-key>— the public key itself. MANDATORY. An emptyp=value revokes the key (signatures referencing this selector will fail verification).t=y— testing mode (signatures treated as invalid by the verifier even if they otherwise verify). For deployment testing only; remove for production.
A canonical 2048-bit RSA DKIM TXT record looks
like this (with the long p= value
split across multiple character-strings — the
receiver concatenates them transparently):
mail2026._domainkey.example.com. 300 IN TXT ( "v=DKIM1; k=rsa; h=sha256; s=email; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvfZ..." "...wWl0iiE9dQwIDAQAB" )
An Ed25519 DKIM TXT record fits comfortably in a single string because the public key is only 32 bytes:
ed2026._domainkey.example.com. 300 IN TXT "v=DKIM1; k=ed25519; h=sha256; s=email; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="
The 255-byte character-string limit on DNS TXT records comes from RFC 1035 section 3.3.14. A single TXT record can contain multiple character-strings, each enclosed in its own quotes, and the receiver resolver concatenates them before passing the body to the DKIM parser. This is a DNS encoding detail with no cryptographic significance; it is the most common source of DKIM TXT-record errors when an operator pastes a long key into a DNS provider UI that does not split it automatically.
11. Best practices for DKIM cryptography
- Publish 2048-bit RSA keys at minimum. Do not publish new 1024-bit keys in 2026 or later. NIST SP 800-57 part 3 deprecates 1024-bit RSA for new signing keys.
- Use
rsa-sha256, neverrsa-sha1. RFC 8301 prohibits SHA-1. Receivers SHOULD reject SHA-1 signatures. - Declare
c=relaxed/relaxedexplicitly. The default (simple/simple) breaks easily on legitimate transits. Relaxed/relaxed is the de-facto standard. - Use
h=sha256in the DNS TXT record. Modern DKIM verifiers prefer explicit declaration; some legacy verifiers default to allowing SHA-1, which is unsafe. - Use
s=emailin the DNS TXT record. Theemailservice-type value scopes the key to email signing and prevents misuse for other DKIM applications. - Rotate signing keys regularly. Monthly or quarterly for high-value senders; annually at minimum. See DKIM key rotation for the operational procedure.
- Publish a short TTL on the DKIM TXT record. 300 seconds (5 minutes) is a reasonable default. Short TTLs enable fast emergency key rotation if the private key is compromised.
- Consider Ed25519 (RFC 8463) for new deployments. Dual-algorithm deployment (RSA-2048 selector + Ed25519 selector) gives modern receivers the smaller, faster signature while maintaining compatibility with receivers that do not yet support Ed25519.
- Sign with as many headers as
practical. The
h=tag should include From, To, Cc, Subject, Date, Message-ID, Reply-To, References, In-Reply-To, and any other headers an attacker could usefully manipulate. Signing more headers broadens the bytes the signature binds. - Sign From: at least once,
twice if possible. The
h=tag can list From: twice; the second occurrence binds against From-header injection attacks where an attacker prepends a second From: header that some MUAs display in preference to the original. - Protect the private key. Store on disk with mode 0400 owned by the MTA user. Do not commit to version control. Treat compromise as a security incident requiring immediate rotation.
- Monitor DMARC aggregate reports
for DKIM failures. A sudden
increase in
dkim=failin DMARC RUA reports often indicates a canonicalization mismatch, key-rotation misstep, or content-modifying intermediary.
12. Common DKIM cryptography mistakes
- Publishing a 1024-bit RSA key in 2026. Deprecated by NIST. Use 2048-bit at minimum.
- Forgetting to split a 2048-bit RSA key across multiple TXT character-strings. A 392-character base64-encoded key does not fit in a single 255-byte string. Some DNS provider UIs split automatically; others require the operator to insert quote-string boundaries manually.
- Including the
-----BEGIN PUBLIC KEY-----and-----END PUBLIC KEY-----PEM armour in thep=tag. Thep=tag holds only the raw base64-encoded key bytes, not the PEM-wrapped form. Strip the armour and the embedded newlines before pasting into the DNS UI. - Using
rsa-sha1. Prohibited by RFC 8301 since 2018. Modern receivers MAY reject SHA-1 signatures outright. - Forgetting
t=yin production. The testing-mode flag instructs verifiers to treat the signature as invalid even if it otherwise verifies. Remove from the TXT record before going live. - Mixing canonicalization
algorithms. The
c=tag declares one pair (header/body); the signer must apply the declared pair consistently. A mismatch between signer and verifier results in body-hash-mismatch on every message. - Not including the
DKIM-Signature header with empty
b=in the signed-headers blob. The DKIM-Signature header is itself signed (with theb=placeholder) so the signature binds the metadata of its own construction. Forgetting this step produces signatures that fail verification at every receiver. - Reusing a selector after publishing a different public key. Once published, a selector should be retired after rotation rather than reused. Receivers may cache the old public key briefly even after DNS TTL expiry.
- Empty
p=tag without intent to revoke. An emptyp=value tells the verifier the key has been revoked; signatures referencing this selector will fail. A misconfigured emptyp=can accidentally revoke a live signing key. - Forgetting that DKIM does not
sign the SMTP envelope.
MAIL FROMandRCPT TOare NOT covered by DKIM. This is the structural reason DKIM cannot prevent replay attacks — an attacker can change the envelope while keeping the body and signed headers (and therefore the signature) intact.
13. FAQ — common questions about DKIM cryptography
- What is DKIM cryptography?
- DKIM cryptography is the public-key (asymmetric) digital-signature scheme used by DomainKeys Identified Mail (RFC 6376) to bind a signing identity to the body and selected headers of an email message. The signer holds a private key; the public key is published in DNS under a selector-scoped TXT record. The signing algorithm is rsa-sha256 (RSA over SHA-256) by default, with ed25519-sha256 (RFC 8463) as the modern alternative.
- How does DKIM signing actually work step by step?
- Five steps. Step 1: canonicalize the message body (relaxed/relaxed is recommended). Step 2: compute a SHA-256 hash of the canonicalized body and base64-encode into the bh= tag. Step 3: assemble the canonicalized signed-headers blob including the DKIM-Signature header itself with empty b= placeholder. Step 4: sign the SHA-256 hash of the blob with the private key (RSA-2048 or Ed25519). Step 5: base64-encode the signature into the b= tag. The completed DKIM-Signature header is attached to the outgoing message.
- Is RSA-1024 still safe for DKIM in 2026?
- No. RFC 8301 sets the floor for DKIM RSA keys at 1024 bits but recommends 2048; NIST SP 800-57 part 3 deprecates 1024-bit RSA for new signing keys. Public-research factoring of 1024-bit RSA has not been demonstrated but is within projected reach of nation-state-scale resources by the late 2020s. Publish 2048-bit RSA at minimum; Ed25519 (RFC 8463) is the modern alternative.
- Should I use Ed25519 instead of RSA for DKIM?
- Ed25519 is preferable cryptographically: shorter keys (32 bytes versus 256 bytes for RSA-2048), faster signing and verification, no 255-byte TXT-segment splitting, strong cryptographic margins. The practical caveat is receiver-side support. The canonical safe deployment publishes BOTH an RSA-2048 selector AND an Ed25519 selector and signs with both; receivers verify whichever they support (RFC 8463 section 5).
- What is the DKIM body hash?
- The DKIM body hash is the base64-encoded SHA-256 digest of the canonicalized message body, published in the bh= tag of the DKIM-Signature header. It gives DKIM verifiers a way to confirm the message body has not been modified in transit. The body hash is computed AFTER body canonicalization, so legitimate transit normalisation does not invalidate it.
- What is SHA-256 in DKIM and why not SHA-1?
- SHA-256 is the cryptographic hash function used by rsa-sha256 and ed25519-sha256 to produce a fixed-length 256-bit digest of the canonicalized body and the signed-headers blob. RFC 8301 deprecates the older rsa-sha1 because SHA-1 was demonstrated to admit practical collisions in 2017 (the SHAttered attack). Modern signers MUST use rsa-sha256 or ed25519-sha256.
- What is DKIM canonicalization and why does it matter cryptographically?
- Canonicalization is the normalisation step that prepares the body and signed headers for hashing. The recommended combination is relaxed/relaxed, which tolerates trailing-whitespace stripping, header refolding, and other common transit modifications. Without canonicalization, the body and signed-headers hashes would be invalidated by virtually any benign transit modification by intermediate MTAs.
- Why is my DKIM public key split across multiple strings in DNS?
- DNS TXT record character-strings are limited to 255 bytes per RFC 1035 section 3.3.14. A 2048-bit RSA public key base64-encoded with DKIM tags is approximately 420 bytes long and must be split across multiple character-strings (each in its own quotes) within a single TXT record. The receiver resolver concatenates them transparently. Ed25519 public keys (44 bytes base64) fit comfortably in a single string.
15. Audit your DKIM cryptography now
DMARC Analyzer's
Domain Security Checker
performs a live recursive lookup of any
published DKIM public key under a given
selector (via
includes/DnsChecker.php),
reporting the key algorithm
(k=rsa or k=ed25519),
the inferred key size, the published hash
declaration (h=sha256 or default),
the service-type scope (s=email),
and the DNS TTL of the TXT record. Use it to
audit your current DKIM selector and confirm
your published key is at least 2048 bits with
SHA-256 declared. The
Email Header Analyzer
parses the DKIM-Signature header from any
captured message (via
includes/EmailHeaderParser.php)
and surfaces the signer's algorithm
(a=rsa-sha256 or
a=ed25519-sha256), the
canonicalization pair (c=relaxed/relaxed),
the signed-headers list, the body hash, and
the signature — exactly the cryptographic
fields documented on this page.