Learn

What is DKIM?

DKIM (DomainKeys Identified Mail) signs each message so receivers can verify it came from you and wasn't changed along the way. Here is how signing and checking work, what a signature contains, and what each provider does differently.

How DKIM works, end to end

DKIM, defined in RFC 6376, uses a key pair. The private key stays with whoever sends your mail; the public key goes into DNS where anyone can read it. Signing and checking happen at the two ends of the trip:

  1. The sending server chooses which header fields to sign, always including From, and normalizes them and the body according to the canonicalization it picked.
  2. It hashes the body, then signs the chosen headers together with that body hash using the private key.
  3. It adds a DKIM-Signature header that carries the signature and everything needed to check it, including the signing domain (d=) and the selector (s=).
  4. The receiver reads that header and fetches the public key from the TXT record at s._domainkey.d, here s1._domainkey.example.com.
  5. It recomputes the body hash and checks the signature with the public key. If both match, the signature passes: the domain in d= vouches for the message, and the signed parts arrived unchanged.

A message can carry several signatures, for example one from your domain and one from the service that sent it. Each is checked on its own. A signature that fails doesn't necessarily mean the message is fake: a mailing list that adds a footer changes the body, and the old signature no longer matches.

It helps to be clear about what a pass proves. It proves that the domain in d= took responsibility for the message and that the parts it signed weren't altered. It says nothing about whether that domain is the one in the From line, which anyone signing with their own domain could set to yours, and nothing about whether the message is wanted. Connecting the signing domain to the From address is DMARC's job, and judging the content is left to the receiver's filters.

Anatomy of a signature

Here is a shortened signature, the way it appears in the headers of a message:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  d=example.com; s=s1; t=1792224000;
  h=from:to:subject:date:message-id;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
  b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSb…
TagWhat it means
v=1Signature version. Always 1.
a=rsa-sha256The algorithm: an RSA key over a SHA-256 hash. Ed25519 keys use ed25519-sha256.
c=relaxed/relaxedCanonicalization for headers and body. relaxed tolerates small changes such as extra whitespace; simple, the default, tolerates almost none.
d=example.comThe signing domain: the domain taking responsibility for the message, and the one DMARC compares with the From domain.
s=s1The selector, which together with d= says where the public key is published.
t=When the message was signed, as a Unix timestamp. Optional, as is x=, an expiry time.
h=The header fields that were signed, in order. From must always be among them.
bh=A hash of the message body after canonicalization.
b=The signature itself, over the listed headers and the body hash.

The key record in DNS is much shorter. It usually holds v=DKIM1, the key type in k= (RSA when it is left out) and the base64 public key in p=. An empty p= means the key was revoked on purpose, and t=y marks a domain that is still testing DKIM, whose signatures receivers should treat like no signature at all.

A worked example

example.com sends its newsletter through a mailing service. During setup, the service asked for a CNAME at s1._domainkey.example.com pointing to a key it hosts, so it can rotate the key without anyone touching your DNS again. Every newsletter now leaves with a signature that says d=example.com and s=s1.

When a receiver checks one of those messages, its DNS lookup follows the CNAME to the key:

s1._domainkey.example.com.          CNAME  s1.domainkey.mailer.example.net.
s1.domainkey.mailer.example.net.    TXT    "v=DKIM1; k=rsa; p=MIIBIjANBgkqh…"

The body hash matches, the signature verifies, and DKIM passes for example.com. The From line says news@example.com, so the signing domain and the From domain are the same, and DMARC passes too. That holds even though SPF passed only for the service's own bounce domain, which doesn't align with yours.

Now follow the same message further:

  • A reader's old university address forwards it unchanged to their real mailbox. The final receiver sees a connection from the university's server, which your SPF record doesn't list, so SPF fails. The signature, though, still matches: nothing it covers was changed. DKIM, and with it DMARC, still passes.
  • A mailing list adds an unsubscribe footer and tags the subject. The body hash no longer matches and the subject was a signed header, so the signature fails. This is the case where DMARC can fail for mail that was legitimate; mailing lists usually work around it by rewriting the From line to their own address.

That difference is why DKIM carries DMARC for mail sent through other companies' servers. Those services usually send with their own envelope sender, so SPF can't align with your domain, but when they sign with your domain's key, DMARC passes anyway. DMARC fails even though SPF passes walks through that fix in detail.

Selectors

The selector is what lets one domain publish many keys, one per sending service or per rotation, each at its own name under _domainkey. You need its exact name to look a key up, and how to find your DKIM selector shows three ways to get it.

Key length and algorithms

RFC 8301 sets 1024 bits as the floor: signers must use RSA keys at least that long, and verifiers must not treat a signature made with a shorter key as valid. Signers should use at least 2048 bits, and verifiers must handle keys up to 4096. The same RFC retired SHA-1: rsa-sha1 must not be used for signing or verifying. So use 2048-bit RSA keys for anything new; 1024-bit keys still pass but are the minimum.

RFC 8463 added Ed25519, a much shorter key that fits in a single DNS string. Verifiers must support it and signers should. A message can carry an RSA and an Ed25519 signature side by side, as the sample message in RFC 8463 does.

When you rotate, publish the new key under a new selector, switch signing to it, and keep the old selector published for a few days so mail already in transit still verifies. RFC 6376 describes exactly this overlap.

Provider gotchas

  • Google Workspace makes you wait. After Gmail is turned on for a domain, Google says it can take 24 to 72 hours before the Admin console will generate a DKIM key. The default selector is google. Publish the TXT record before you click Start authentication, and expect the console to keep warning for up to 48 hours.
  • Long keys get split. A 2048-bit key is longer than the 255 characters one TXT string can hold. Some DNS hosts split it for you; with others you enter several quoted strings in one record. Google offers a 1024-bit key for hosts that can't store the longer one.
  • Microsoft 365 uses two CNAMEs, and only one is active. Microsoft has you publish selector1._domainkey and selector2._domainkey; the second is used only after a key rotation. Copy the targets from the Defender portal or PowerShell, because the old and new formats can't coexist for the same selector. Mail from the initial onmicrosoft.com domain is signed automatically.
  • Amazon SES selectors are random. Easy DKIM gives you three CNAME records whose names contain generated tokens, so no list of common selectors will find them. With your own key, SES accepts RSA keys from 1024 to 2048 bits.
  • SendGrid can manage it for you. With automated security on, SendGrid asks for CNAMEs at s1._domainkey and s2._domainkey and updates the records behind them itself when your account setup changes.

Check yours

The DKIM checker looks up your keys, measures their length and catches revoked and test-mode keys. If you sign mail on your own server, the DKIM generator creates a key pair in your browser.

DKIM setup guides by service

Mailbox providers

Marketing platforms

Transactional email

Help desks

Related tools and articles

We use Google Analytics cookies only if you accept. Privacy policy