MailDingo

Read the fields

The DKIM-Signature header

A DKIM-Signature is a domain's cryptographic stamp on a message. d= says who signed, s= which key, h= which headers are protected. Here's every tag.

6 min read · updated 2026-10-26 · 13 RFC sections cited

A DKIM-Signature header is a digital signature added by a sending domain (for the big picture, see DKIM explained). The most important tags are d=, the domain that takes responsibility for the message; s=, the selector that says which public key to fetch from DNS; and h=, the list of headers the signature protects. The header alone tells you who claims to have signed. Whether the signature actually verified is recorded by your provider in Authentication-Results as dkim=pass or dkim=fail. For DMARC, the d= domain also has to align with the From domain.

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
        s=s2026; t=1793020445; x=1793625245;
        h=from:to:subject:date:message-id:reply-to:mime-version:content-type:from;
        bh=yR5mU0dN0Q7m3hQx8Vf1Lw2ZcP4aJtB6kE9sWnG3oHI=;
        b=Q1zK7xV2... (long base64 signature) ...

Every tag

RFC 6376 §3.5 defines the tags. Tags can appear in any order, and unknown tags are ignored.

Tag Required? Meaning
v= Yes Version. Always 1.
a= Yes Algorithm: rsa-sha256, or ed25519-sha256 (RFC 8463). rsa-sha1 is obsolete; RFC 8301 §3.1 says it must not be used for signing or verifying.
b= Yes The signature itself, in Base64. Long and meaningless to read.
bh= Yes Hash of the canonicalized body. If the body changes in transit, this stops matching and DKIM fails with a "body hash did not verify" error.
c= No Canonicalization, header/body: simple or relaxed each. Default simple/simple; c=relaxed alone means relaxed/simple.
d= Yes Signing domain (SDID). The domain responsible, and the one DMARC compares with From.
h= Yes Colon-separated list of signed header fields, in order. Must include from.
i= No Agent or user identifier (AUID). Looks like an address; its domain must be d= or a subdomain of it. Defaults to @ + d=.
l= No Body length: only this many bytes of the body are signed. Risky; see below.
q= No Key lookup method. Only dns/txt exists; it's the default.
s= Yes Selector: picks which key under d= to use.
t= Recommended Signing time, in seconds since 1970 UTC.
x= Recommended Expiry time, same format. Verifiers may treat the signature as invalid after it.
z= No Copies of the original header values, for diagnostics only. Rarely seen.

To turn t= into a date, use any Unix-timestamp converter (date -u -d @1793020445 on Linux, date -u -r 1793020445 on macOS): this one is 26 Oct 2026, 13:14:05 UTC, and the x= above is exactly seven days later. A t= far from the message's Date header is worth noticing, since it might mean a replayed signature or a wrong clock.

d= and s=: where the key lives

The verifier builds a DNS name from the selector and the domain: s=s2026 and d=example.com mean a TXT lookup at s2026._domainkey.example.com (RFC 6376 §3.6.2.1). That record holds the public key.

Selectors let a domain run several keys at once: one per mail service, per region, or per year for rotation (RFC 6376 §3.1). They often reveal the platform: selectors like google, selector1 and selector2 (common with Microsoft 365), k1, s1 or long random strings are each associated with particular services. Treat that as a hint, not proof, since anyone can name a selector anything.

d= is what matters for trust. A valid signature proves that whoever controls d='s DNS signed this message. It says nothing about the From address unless d= aligns with it, because any domain, including an attacker's, can sign any message (RFC 9989 §4.4.1). See DMARC alignment.

h=: what the signature protects

h= lists the header fields covered. Anything not listed can be changed or added after signing without breaking the signature. So:

  • from is mandatory (RFC 6376 §5.4).
  • Well-run signers also include subject, date, to, cc, reply-to, message-id and the MIME headers. RFC 6376 §5.4 recommends signing fields like Date, Subject, Reply-To and the MIME fields.
  • If subject or reply-to is missing from h=, those fields could have been altered en route by someone else without the signature noticing. Unusual for major senders, worth noting on a suspicious message.

Over-signing

You'll often see a header name listed more times than it appears, as in h=from:…:from or h=…:reply-to:reply-to. That's deliberate. A name listed beyond the number of actual copies is treated as an empty field. So if someone later adds a second From or Reply-To, the signature breaks (RFC 6376 §5.4.2, §8.15). This defends against an attack in which an extra From header is slipped into a genuinely signed message and some mail apps display the wrong one. Over-signing is good practice.

c=: canonicalization

Mail gets reformatted in transit: whitespace changes, lines are rewrapped, header case changes. Canonicalization defines how much of that the signature tolerates (RFC 6376 §3.4):

  • simple tolerates almost nothing.
  • relaxed ignores changes in header case, runs of whitespace, and trailing whitespace.

c=relaxed/relaxed is the most common choice because it survives ordinary handling better.

l=: why it's risky

l= signs only the first N bytes of the body. The idea was to let mailing lists append footers without breaking the signature. The problem is that anyone can append content, not just a list. An attacker who gets hold of a genuinely signed message can add their own HTML after the signed part, and with some MIME and HTML tricks the added content can be what the reader actually sees. The signature still passes (RFC 6376 §8.2). The RFC advises signers to be very wary of l= and says receivers may ignore signatures that use it.

Watch out: If a suspicious message passes DKIM and its signature has an l= value smaller than the actual body, the passing signature doesn't vouch for the whole message.

Multiple signatures

Two or more DKIM-Signature headers are common and normal (RFC 6376 §4.1):

  • ESP plus your own domain. A company sending through a mail service often gets one signature with d= the company's domain (aligned, so it counts for DMARC) and another with the service's domain, used by the service for its own reputation.
  • Mailing lists. A list may add its own signature on top of the original.
  • Algorithm transition. A signer may sign twice, with RSA and Ed25519, using different selectors (RFC 8463 §6).

Each signature is verified independently, and Authentication-Results usually reports one dkim= result per signature, distinguished by header.d and header.b (the first few characters of b=). For DMARC, one aligned pass is enough.

Ed25519 signatures

RFC 8463 added a=ed25519-sha256. Ed25519 keys are much shorter than RSA keys, so the DNS record fits easily in a single TXT string (RFC 8463 §3). Because not all verifiers support it yet, senders that use it usually add an RSA signature alongside. If the Ed25519 signature gets a non-pass result (or no result) while the RSA one passes, the receiver probably doesn't support Ed25519 yet; the exact result word varies by receiver.

Reading one in practice

  1. Note d= and compare it with the From domain.
  2. Find the matching dkim= result in your provider's Authentication-Results (header.d should equal this d=).
  3. Glance at h= for subject and reply-to, and check for l=.
  4. With several signatures, ask which d= aligned.

The analyser explains each DKIM-Signature and checks whether d= aligns with the From domain.

Got a suspicious email?

Paste its headers into the analyser. It runs on your device and explains every result on this page.

Open the analyser

Next in Read the fields: The Date header →