DKIM Explained: How Signing and Verification Actually Work
VigilDog Team · September 10, 2026 · 7 min read
DKIM is the part of email authentication that most people set once and never think about again, until a forwarded newsletter fails, a vendor rotates keys, or a DMARC report shows your own mail failing. Understanding how DKIM works, end to end, turns those incidents from mysteries into five-minute fixes. This guide walks the full path: what gets signed, what travels with the message, and exactly what the receiving server checks.
What DKIM actually proves
DKIM (DomainKeys Identified Mail) attaches a cryptographic signature to outgoing email so a receiving server can confirm two things: that the message was authorized by the signing domain, and that specific parts of it were not altered in transit. It does not encrypt the message and it does not prove who the human sender is, it proves that a domain took responsibility for the message and that the signed content is intact.
The mechanism is ordinary public-key cryptography. The sending system holds a private key and signs each outgoing message with it. The matching public key is published in DNS as a TXT record. Any receiver can fetch that public key and verify the signature. Because only the holder of the private key can produce a signature that validates against the published public key, a passing DKIM check is strong evidence the mail genuinely originated from infrastructure the domain owner controls.
How a message gets signed on the way out
When your mail server (or provider like Google Workspace, Microsoft 365, SendGrid, or Postmark) sends a message, it computes a hash of the message body and a hash over a chosen set of headers, typically From, Subject, Date, To, and a few others. It then signs those hashes with the private key and inserts a new header called DKIM-Signature.
That header is self-describing. The key tags you will see are: v (version), a (the algorithm, almost always rsa-sha256), d (the signing domain), s (the selector), h (the list of headers that were signed, in order), bh (the body hash), and b (the actual signature). The selector matters more than people expect, it lets one domain publish several keys at once. A provider might sign with selector s1 while you rotate to s2, each pointing at a different DNS record, so key rotation never causes downtime.
- d=, the domain claiming responsibility (this is what DMARC aligns against)
- s=, the selector, which chooses which published key to look up
- h=, the ordered list of headers covered by the signature
- bh=, a hash of the (canonicalized) body
- b=, the signature itself, computed over the signed headers
How the receiver verifies it
Verification runs in reverse. The receiving server reads the DKIM-Signature header, takes the domain from d= and the selector from s=, and looks up the DNS TXT record at <selector>._domainkey.<domain>. For a message signed by example.com with selector s1, that query is s1._domainkey.example.com. The record returns the public key.
The receiver then recomputes the body hash and compares it against bh=. If the body was modified, even by a single character, subject to the canonicalization rules, that comparison fails and DKIM fails. If the body hash matches, the receiver rebuilds the signed-header string exactly as the h= tag specifies and uses the public key to verify the b= signature against it. Both checks must pass. This two-part design is why DKIM can catch tampering in the body independently of the headers.
One nuance worth internalizing: only the headers listed in h= are protected. Headers not listed can be added or changed without breaking the signature. Good signing configurations therefore cover the headers that matter for trust, notably From, and often over-sign to prevent an attacker from adding a second From header.
Why DKIM survives forwarding (and when it doesn't)
DKIM's headline advantage over SPF is that it travels with the message. SPF checks the connecting server's IP against the sending domain's policy, so the moment a message is forwarded through a new server, SPF typically breaks. DKIM does not care about the IP path, as long as the signed headers and body are untouched, the signature still validates after multiple hops.
It breaks when something in the signed content changes. Mailing lists that append an unsubscribe footer, gateways that rewrite subjects with a [EXTERNAL] tag, or antivirus systems that modify the body will invalidate the body hash. This is exactly the failure mode ARC (Authenticated Received Chain) was designed to paper over, and it's why a DMARC policy should lean on both SPF and DKIM alignment rather than either alone. If you're untangling one of these, our guide to fixing SPF, DKIM and DMARC walks through the common breakages.
Operating DKIM without surprises
Two operational habits prevent almost every DKIM incident. First, use adequate key strength, 2048-bit RSA is the practical standard; 1024-bit keys still work but are weak and some receivers flag them. Watch out for DNS providers that truncate long TXT records, which quietly corrupts the public key. Second, rotate keys on a schedule and stage the rotation with a new selector so the old key stays live until every in-flight message has been delivered and verified.
The failure you can't see coming is the one that matters: a key removed during a DNS migration, a provider that stopped signing after a plan change, or a selector that never got published in the first place. Verifying your published record now takes a few seconds with our free DMARC and email-auth checker, and if you run mail for clients, continuous monitoring catches a missing key the day it disappears rather than the week the campaign underperforms. That's the same reasoning behind treating DKIM as something you monitor, not just configure.
