1. Library
  2. Computer Networks
  3. Email Protocols
  4. Authentication

Updated 8 hours ago

DKIM (DomainKeys Identified Mail) is email's answer to a simple question: Is this message exactly what the sender sent?

SPF asks "did this come from the right place?" DKIM asks "is this the same message that was sent?" These are different questions. SPF validates the path. DKIM validates the content.

When you receive an email, you're trusting that nothing changed in transit—that no one added a malicious link, altered the amount in an invoice, or modified the instructions in a message from your boss. DKIM provides cryptographic proof that the message you received is byte-for-byte what the sender transmitted.

How DKIM Works

DKIM uses public-key cryptography:

  1. The domain publishes a public key in DNS. Anyone can look it up.

  2. When sending email, the mail server creates a signature. It hashes specific parts of the message (headers and body), then encrypts that hash with the domain's private key.

  3. The signature travels with the message. It's added as a DKIM-Signature header.

  4. The receiving server verifies. It looks up the public key, decrypts the signature, recomputes the hash, and compares. If they match, the message is authentic and unmodified.

This is the same cryptography that secures HTTPS, digital contracts, and cryptocurrency. The math is the same. The application is email.

The Signature Anatomy

A DKIM signature looks like this:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=selector1;
    h=from:to:subject:date:message-id;
    bh=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=;
    b=gCN9nNMk+9p2q3VhR8BVqR9tVFPLl9V7q1z5XpHBvUl8oVhFQfqLX2+
      YaU8p9VnD3vR2yT4qBzQwN1XhJqpVrL==

d=example.com — The domain making the claim. This is who's putting their reputation on the line.

s=selector1 — Which key to use. Domains can have multiple keys (more on this below).

h=from:to:subject:date:message-id — Which headers are signed. If these change, the signature breaks.

bh=... — Hash of the message body.

b=... — The actual signature: the encrypted hash of the headers and body hash.

a=rsa-sha256 — The algorithm. RSA encryption with SHA-256 hashing.

c=relaxed/relaxed — How strict to be about whitespace changes (relaxed means minor formatting changes won't break the signature).

The Public Key in DNS

The public key lives at a predictable location:

selector._domainkey.example.com

Query it and you get:

"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5N3ln..."

That p= value is the public key. Anyone can use it to verify signatures, but only the holder of the private key can create them.

Why Selectors Exist

Selectors let domains use multiple DKIM keys simultaneously:

selector1._domainkey.example.com    →  Key A
selector2._domainkey.example.com    →  Key B
marketing._domainkey.example.com    →  Key C

Key rotation: Deploy a new key while the old one still works. Transition gradually.

Different systems: Your corporate mail server uses one key, your marketing platform uses another, your transactional email service uses a third.

Security boundaries: If marketing's key is compromised, your corporate email remains secure.

Canonicalization: Handling Reality

Email passes through many servers. Each might adjust whitespace, wrap long lines, or normalize line endings. Strict byte-for-byte matching would fail constantly.

Canonicalization defines how much flexibility to allow:

Simple: Exact match. Any change breaks the signature. Secure but fragile.

Relaxed: Whitespace normalization allowed. Headers converted to lowercase. Trailing whitespace removed. Survives the real world.

Most deployments use c=relaxed/relaxed—secure enough to detect meaningful tampering, flexible enough to survive normal email routing.

What to Sign

You choose which headers to include in the signature:

Always sign:

  • From (the most important—this is the claimed sender identity)
  • To
  • Subject
  • Date
  • Message-ID

Sign if present:

  • Reply-To
  • CC
  • In-Reply-To
  • References
  • Content-Type

Never sign:

  • Received (changes at every hop)
  • DKIM-Signature itself

Anything unsigned can be modified without breaking the signature. Sign everything that matters.

Verification Results

Receiving servers report what happened:

ResultMeaning
passSignature verified. Message is authentic.
failSignature invalid. Message was modified or forged.
noneNo signature present.
temperrorTemporary failure (DNS timeout). Try again later.
permerrorPermanent failure (malformed signature, missing key).

Results appear in the Authentication-Results header:

Authentication-Results: mx.receiver.com;
    dkim=pass header.d=example.com header.s=selector1

DKIM's Limitations

Mailing lists break signatures. When a mailing list adds a footer or modifies the subject line, the hash changes and DKIM fails. This is the fundamental tension between message modification and message authentication.

No replay protection. DKIM proves a message was signed by the domain—not when, not to whom. An attacker could capture a legitimately signed message and send it to different recipients. You can prove you said something. You can't prove you only said it once.

Key compromise is catastrophic. If attackers get your private key, they can sign any message as your domain until you rotate keys and wait for DNS propagation.

The d= domain isn't necessarily the From address. I can sign a message with d=attacker.com while the From header says ceo@yourcompany.com. DMARC exists to close this gap by requiring alignment.

DKIM vs. SPF

SPF: Validates the sending server's IP address. Breaks when email is forwarded (the forwarder's IP isn't authorized).

DKIM: Validates message content through cryptographic signature. Survives forwarding because the signature travels with the message.

They protect against different attacks. SPF stops unauthorized servers. DKIM stops message tampering. Use both.

Third-Party Signing

When you use a service like SendGrid, Mailgun, or your company's email provider, they sign messages for you.

By default, they sign with their domain (d=sendgrid.net). For DMARC alignment, you want them to sign with your domain.

The setup:

  1. The service generates DKIM keys for your domain
  2. They give you DNS records to publish
  3. You add those TXT records to your DNS
  4. They sign outbound mail with your domain's key

Now your marketing emails, transactional notifications, and corporate mail all carry DKIM signatures from your domain—consistent authentication across every channel.

Best Practices

Use 2048-bit RSA keys. 1024-bit is the minimum, but why settle for minimum?

Rotate keys annually. Create the new selector, deploy it, wait for DNS propagation, switch signing, then remove the old key.

Protect private keys. These are the keys to your domain's email identity. Treat them accordingly.

Use relaxed canonicalization. c=relaxed/relaxed handles the real world.

Monitor with DMARC reports. They'll tell you when DKIM is failing and why.

Sign all outbound mail. Every unsigned message is a gap in your authentication.

Frequently Asked Questions About DKIM

Was this page helpful?

😔
🤨
😃