DKIM authentication: digital signatures and security gaps

How DKIM's cryptographic signatures work, where they fall short, and why DMARC is needed to close the alignment gap.

SPF checks that an email comes from an authorized server. But what if a message is altered after it leaves that server? And what if someone forwards the email, making SPF useless? That is the problem DKIM was designed to solve. This guide explains how DKIM works, what it protects, and where it still falls short without DMARC.

What you will learn

Why DKIM exists and what problem it solves that SPF cannot
How cryptographic signatures protect message integrity
The blind spot: why DKIM alone does not stop spoofing
Key management best practices: rotation, key size, and secure storage

The problem: SPF does not travel with the message

SPF verifies the sending server's IP address. That works well for direct delivery. But email often passes through intermediaries: forwarding services, mailing lists, security gateways. Each hop changes the sending IP. When that happens, SPF breaks.

SPF also has another limitation: it cannot tell you whether the message was modified in transit. A server could pass SPF and still deliver a tampered message.

DKIM solves both problems. Instead of checking the server, it signs the message itself. The signature travels with the email, no matter how many servers it passes through.

What is DKIM?

DKIM (DomainKeys Identified Mail) is an email authentication method defined in RFC 6376. It lets the sender attach a digital signature to their message. That signature proves two things: the message came from a server authorized by the domain owner, and the message was not modified in transit.

The wax seal analogy

Think of DKIM like sending a sealed letter with your family crest stamped in wax. If the wax is intact and the seal matches your registered crest, the recipient knows two things: the letter came from you, and nobody opened it along the way.

But here is the catch. The seal only proves who sealed the letter. It does not prove that the seal matches the name on the letterhead inside. Someone could seal a letter with their own crest while writing your name at the top. That is DKIM's biggest limitation, and it is why DMARC exists.

Why DKIM matters

DKIM gives you three things that SPF alone cannot provide:

  • Message integrity. If a DKIM signature is valid, the email was not altered in transit. Headers, subject line, body: all verified
  • Survives forwarding. Unlike SPF, DKIM signatures travel with the message. A forwarded email keeps its original signature intact (unless the content is modified)
  • Better deliverability. Major email providers (Google, Microsoft, Yahoo) use DKIM as a positive signal for inbox placement. As documented by Google's DKIM guide, properly authenticated messages are less likely to be marked as spam

But DKIM is not bulletproof. It is one part of a system that needs DMARC to connect the dots. More on that below.

How DKIM works

DKIM uses public-key cryptography. The sending server signs the message with a private key. The receiving server verifies the signature using a public key published in DNS.

1

The domain owner generates a key pair

A private key (kept secret on the mail server) and a public key (published as a DNS TXT record).

2

The sending server signs outgoing emails

It selects specific headers (From, Subject, Date, etc.) and the body, creates a hash, and signs the hash with the private key. The signature is added as a DKIM-Signature header.

3

The receiving server verifies the signature

It reads the d= (domain) and s= (selector) from the DKIM-Signature header, fetches the public key from DNS, and verifies that the signature matches. If it matches, DKIM passes.

Reading a DKIM-Signature header

When you inspect an email's raw headers, the DKIM-Signature tells you which domain signed it, which key was used, and what parts of the message were covered. Understanding these fields helps you diagnose authentication failures.

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mail; t=1640995200; h=from:to:subject:date:message-id; bh=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=; b=dGVzdCBzaWduYXR1cmUgZGF0YSB0cnVuY2F0ZWQgZm9yIHJlYWRhYmlsaXR5
Tag Value What it means
d= example.com The domain claiming responsibility for this email
s= mail The selector. Used to find the public key at mail._domainkey.example.com
a= rsa-sha256 Signing algorithm. RSA with SHA-256 (the current standard)
c= relaxed/relaxed Canonicalization for header/body. "Relaxed" tolerates whitespace changes
h= from:to:subject:... Which headers are covered by the signature
bh= (base64 hash) Hash of the email body. If the body changes, this breaks
b= (base64 signature) The actual cryptographic signature

DKIM's blind spot: the alignment gap

This is the most important thing to understand about DKIM. It authenticates a domain, but it does not check whether that domain matches the visible "From" address.

How an attacker exploits this gap

An attacker owns attacker.com with a perfectly valid DKIM setup. They send an email with:

From: [email protected] <-- what the recipient sees DKIM-Signature: d=attacker.com; s=mail <-- the actual signer

The DKIM check passes, because the signature is valid for attacker.com. But the recipient sees [email protected]. Without DMARC, nothing connects these two domains. The email looks legitimate.

DMARC closes this gap by requiring alignment: the d= domain in the DKIM signature must match the domain in the visible "From" header. No match means DMARC fails, regardless of whether the DKIM signature itself is valid.

For a detailed walkthrough of how alignment works in practice, see our guide on why SPF and DKIM pass but DMARC fails.

DKIM DNS record structure

The public key is published as a DNS TXT record. The record name follows the pattern selector._domainkey.yourdomain.com.

# Basic DKIM DNS record (RSA 2048-bit) mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." # Ed25519 record (RFC 8463, smaller and faster) mail._domainkey.example.com. IN TXT "v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEA5U4L3TWP..." # Multiple selectors for different services mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..." # Main server marketing._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..." # Marketing platform api._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..." # Transactional emails

Each service that sends email on your behalf gets its own selector. This lets you rotate keys independently and isolate services from each other.

DNS record parameters

  • v=DKIM1. Version (always DKIM1)
  • k=rsa or k=ed25519. Key type. RSA is universal. Ed25519 (RFC 8463) is smaller and faster, but not all receivers support it yet
  • p=... Public key in Base64 DER format
  • t=y. Test mode. Verifiers must not treat messages from signers in testing mode differently from unsigned email, even if the signature fails. Useful during initial deployment
  • t=s. Restricts the key to non-subdomain identities. If an i= tag is used, its domain must not be a subdomain of d=
  • s=email. Service type restriction (optional)

Handling long keys in DNS

DNS TXT records limit each string to 255 characters. Since 2048-bit RSA keys exceed this limit, the key must be split into multiple quoted strings within the same record. Most DNS providers handle this automatically, but if you edit zone files by hand, an improperly split key will cause validation to fail.

# Incorrect: single long string (may be truncated) "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki...very_long_key...AQAB" # Correct: split into multiple quoted strings "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki..." "...continuation..." "...AQAB"
Technical deep dive: key generation, canonicalization, and signing

Key generation

# Generate RSA 2048-bit key pair (RFC 8301 minimum: 1024-bit, recommended: 2048-bit) openssl genrsa -out dkim_private.key 2048 openssl rsa -in dkim_private.key -pubout -outform DER | base64 -w 0 > dkim_public.key # Generate Ed25519 key pair (RFC 8463) openssl genpkey -algorithm Ed25519 -out ed25519_private.key openssl pkey -in ed25519_private.key -pubout -outform DER | base64 -w 0 > ed25519_public.key

Canonicalization

Before signing, the message is "canonicalized", which means it is normalized to handle variations introduced by email processing. There are two modes:

Simple

Exact match. Any change (even extra whitespace) breaks the signature. More secure, but fragile.

Relaxed (recommended)

Normalizes whitespace and header casing before signing. Tolerates minor formatting changes during transit.

The c= tag specifies both modes as header/body. Most implementations use c=relaxed/relaxed.

Signing process (step by step)

1. Select headers to sign (From, Subject, Date, Message-ID, etc.) 2. Canonicalize selected headers and body 3. Create SHA-256 hash of the canonicalized content 4. Sign the hash with the private key (RSA-PKCS1-v1_5 or Ed25519) 5. Encode the signature in Base64 6. Add the DKIM-Signature header to the message

Recommended signature configuration

# Headers to always sign h=from:to:subject:date:message-id:reply-to # Sign "from" (required for DMARC alignment) # Sign "subject" (user-visible, often manipulated) # Sign "date" and "message-id" (prevent replay) # Recommended parameters a=rsa-sha256 # SHA-256, never SHA-1 c=relaxed/relaxed # Tolerant of whitespace variations t= # Include timestamp for replay protection

Common pitfalls

Signatures broken by email processing

DKIM is fragile to message modifications. Mailing list footer additions, subject line prefixes like "[List]", anti-virus scanners, and content filters can all invalidate a signature. Any change to a signed header or the body breaks the verification. ARC (RFC 8617) provides a solution by preserving authentication results through these modifications. Gmail, Outlook, and Yahoo all support ARC.

Weak or outdated keys

RFC 8301 (2018) set a minimum of 1024-bit RSA keys and strongly recommends 2048-bit. It also deprecated SHA-1 in favor of SHA-256. Keys below 1024 bits can be factored with modest computing resources. Always use 2048-bit RSA or Ed25519.

Key rotation neglected

Long-lived keys increase the risk of compromise. Rotate DKIM keys at least once a year. Use overlapping selectors (old and new active simultaneously) for a smooth transition. After rotation, keep the old public key in DNS for a few days so in-transit emails can still be verified.

Multiple DKIM signatures

Some systems add multiple DKIM signatures (e.g., one from your email platform and another from your CRM). This is valid. DMARC only requires that one aligned signature passes.

Test mode for safe deployment

The DKIM standard includes a test mode flag. Adding t=y to your DNS record signals to receivers that you are testing. Verifiers must not treat messages from testing signers differently from unsigned email, even if the signature fails. This lets you deploy DKIM, gather data on signing issues, and fix them without risking your email deliverability. Remove the t=y tag once signing works correctly.

Security strengths and limitations

Strengths

  • Cryptographic integrity. RSA-2048/Ed25519 signatures are extremely hard to forge
  • Tamper detection. Any modification to signed content invalidates the signature
  • Survives forwarding. Unlike SPF, signatures travel with the message
  • Algorithm flexibility. Supports upgrades (SHA-256, Ed25519, future algorithms)
  • Granular control. You choose which headers to sign

Limitations

  • No sender identity check. DKIM authenticates the signing domain, not the "From" address
  • Fragile to modifications. Mailing lists, gateways, and filters break signatures
  • DNS dependency. Vulnerable to cache poisoning, BGP hijacking (mitigated by DNSSEC)
  • Replay attacks. A valid signed message can be resent in different contexts
  • Key compromise. A stolen private key lets attackers sign arbitrary messages

Key management best practices

  • Use 2048-bit RSA or Ed25519. Never deploy keys below 1024 bits (RFC 8301)
  • Rotate annually. Create a new selector, deploy it, then retire the old one after a grace period
  • Restrict access. Private keys should be readable only by the mail server process. Use chmod 600 and appropriate ownership
  • Use separate selectors per service. Your main server, marketing platform, and transactional email service should each have their own key pair
  • Monitor failures. Alert on DKIM verification failures in DMARC aggregate reports
  • Consider DNSSEC. Protects your DKIM DNS records from tampering
Example: key rotation with overlapping selectors
# Step 1: Generate new key and publish it alongside the old one 2025a._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..." # New key 2024a._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..." # Old key (still active) # Step 2: Switch signing to the new selector (2025a) # Step 3: Wait 48-72 hours for in-flight emails to be delivered # Step 4: Remove the old key from DNS 2024a._domainkey.example.com. IN TXT "v=DKIM1; p=" # Revoked (empty p= value)

Validation and testing

# Check if your DKIM DNS record exists dig TXT mail._domainkey.example.com +short # Check from multiple DNS servers dig @8.8.8.8 TXT mail._domainkey.example.com +short dig @1.1.1.1 TXT mail._domainkey.example.com +short # Send a test email and inspect the Authentication-Results header echo "Test DKIM" | mail -s "DKIM Test" [email protected] # In Gmail: Open email > Show original > Look for "dkim=pass"

Remember: A valid DKIM signature does not mean the email is not spoofed. DKIM authenticates the signing domain, not the visible sender. Always combine DKIM with DMARC to enforce alignment between the signature and the "From" address.

Troubleshooting common DKIM failures

Signature broken by email processing

Caused by mailing lists adding footers, anti-virus scanners modifying content, gateways changing headers, or charset conversions. Solution: use c=relaxed/relaxed canonicalization.

DNS resolution failures

Record not yet propagated, syntax errors in the TXT record, or TTL too short causing excessive lookups. Test from multiple DNS servers to confirm propagation.

Clock skew problems

DKIM signatures include a timestamp (t=) and optional expiration (x=). If the signing and verifying servers have different clocks, signatures can appear expired or not-yet-valid. Keep servers synchronized with NTP.

Key not found

The selector in the DKIM-Signature header does not match any DNS record. Verify that the s= value matches the published selector name, and that the DNS record is at selector._domainkey.yourdomain.com.

Next steps

DKIM does not work alone. It needs SPF and DMARC to enforce alignment with the visible From address.

  1. Set up DKIM signing for all your email sources (main server, marketing platform, transactional services)
  2. Configure SPF to define which servers can send email for your domain
  3. Deploy DMARC to enforce alignment between DKIM/SPF and your "From" domain
  4. Monitor reports and fine-tune your configuration

Learn more

DKIM provides cryptographic proof that an email came from an authorized server and was not modified in transit. But it does not check whether the signing domain matches the address the recipient sees. To close that gap, you need DKIM working together with SPF under a DMARC policy.

Was this page helpful? Send us feedback

Last updated: April 2026