DKIM (DomainKeys Identified Mail) adds a cryptographic signature to every email sent from your domain. The sending server signs the message with a private key. The receiving server looks up the corresponding public key in your DNS records and verifies the signature. If the signature is valid, the receiving server knows two things: the email genuinely came from an authorized sender, and the message was not altered in transit.
Where SPF tells receiving servers which servers are allowed to send email for your domain, DKIM proves that the email content itself has not been tampered with. SPF is an IP-based check. DKIM is a content-based check. Together with DMARC, they form the three layers of modern email authentication.
How DKIM works#
DKIM uses the same asymmetric cryptography concept that SSL certificates use: a private key that only the sender has, and a public key that anyone can access.
The process:
- You generate a key pair: a private key and a public key
- The private key is stored on your email sending server (or with your email provider)
- The public key is published as a DNS TXT record on your domain
- When an email is sent, the sending server takes specific parts of the message (headers, body, or both) and generates a hash
- The server encrypts that hash with the private key, producing the DKIM signature
- The signature is added to the email as a
DKIM-Signatureheader - The receiving server extracts the signature, looks up the public key in DNS, and decrypts the hash
- The receiving server independently hashes the same message parts and compares the result
- If the two hashes match, the signature is valid: the message is authentic and unmodified
What the DKIM-Signature header looks like
Every DKIM-signed email contains a header 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=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk2TP
xqCKlEluMrJKxP39MXWBE...
Breaking down the key fields:
| Field | Meaning |
|---|---|
v=1
| DKIM version (always 1) |
a=rsa-sha256
| The signing algorithm. RSA key with SHA-256 hash. |
c=relaxed/relaxed
| Canonicalization method for header/body. “Relaxed” tolerates minor formatting changes (whitespace, case). |
d=example.com
| The domain claiming to have sent the email. This is the domain whose DNS is checked for the public key. |
s=selector1
| The selector, used to locate the specific public key in DNS. More on this below. |
h=from:to:subject:...
| Which headers are included in the signature. |
bh=...
| Body hash. A hash of the email body. |
b=...
| The signature itself. The encrypted hash of the signed headers. |
DKIM selectors explained#
A selector is a label that identifies which DKIM key to use. It is part of the DNS lookup path. When a receiving server needs to verify a DKIM signature with
d=example.com
and
s=selector1
, it looks up:
selector1._domainkey.example.com
The selector is the
s=
value, followed by
._domainkey.
, followed by the domain. This is a standard DNS TXT record.
Why selectors exist
Selectors allow a domain to have multiple DKIM keys active simultaneously. This is useful for:
- Multiple email providers. If you use Microsoft 365 for employee email and SendGrid for transactional email, each provider has its own DKIM key with its own selector. Microsoft might use
selector1andselector2. SendGrid might uses1ands2. - Key rotation. When you replace an old key with a new one, both can coexist during the transition. The old selector stays in DNS until you are confident all in-flight emails signed with the old key have been delivered.
- Separate services. Marketing emails, transactional emails, and internal emails can each use different selectors, making it easier to track which system signed which email.
Each provider chooses its own selector names. You do not pick them — you use whatever the provider specifies when they give you the DKIM DNS record to add.
How DKIM differs from SPF#
SPF and DKIM solve different problems:
| SPF | DKIM | |
|---|---|---|
| What it verifies | The sending server’s IP address is authorized | The email content has not been modified |
| Where the check happens | Envelope sender (return-path) | Message headers and body |
| DNS record type | TXT on the domain root | TXT on selector._domainkey.domain |
| Survives forwarding | No. Forwarding changes the sending IP. | Yes. The signature stays with the message. |
| Protects against | Unauthorized servers sending as your domain | Message tampering in transit |
The forwarding difference is significant. When an email is forwarded, the forwarding server’s IP replaces the original sender’s IP. SPF fails because the new IP is not in the original domain’s SPF record. DKIM survives because the signature is embedded in the email itself and travels with it regardless of which servers relay it.
This is one of the main reasons DKIM exists. SPF alone breaks in common legitimate scenarios like mailing list forwarding, email aliases, and auto-forwarding rules.
Setting up DKIM#
The setup process depends on your email provider. In every case, the provider generates the key pair and gives you a DNS record to add. You do not generate DKIM keys manually unless you run your own mail server.
Microsoft 365
- Sign in to the Microsoft 365 Defender portal
- Go to Email & collaboration > Policies & rules > Threat policies > Email authentication settings
- Select the DKIM tab
- Click your domain
- Microsoft shows you two CNAME records to add to your DNS
The records look like:
Host: selector1._domainkey
Type: CNAME
Value: selector1-yourdomain-com._domainkey.yourtenant.onmicrosoft.com
Host: selector2._domainkey
Type: CNAME
Value: selector2-yourdomain-com._domainkey.yourtenant.onmicrosoft.com
Microsoft uses CNAME records instead of TXT records. The CNAME points to Microsoft’s DNS, where they host the actual DKIM public key. This lets Microsoft rotate keys automatically without requiring you to update your DNS records.
Add both CNAME records to your DNS, then return to the Defender portal and enable DKIM signing for the domain.
Google Workspace
- Sign in to the Google Admin console
- Go to Apps > Google Workspace > Gmail > Authenticate email
- Select your domain
- Click Generate new record
- Choose a key length (2048-bit is recommended)
- Google displays a TXT record to add to your DNS
The record looks like:
Host: google._domainkey
Type: TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqh... (long public key string)
Add the TXT record to your DNS, wait for propagation, then return to the Admin console and click Start authentication.
Mailchimp
- Go to Account > Domains
- Click Authenticate next to your domain
- Mailchimp provides a CNAME record:
Host: k1._domainkey
Type: CNAME
Value: dkim.mcsv.net
Add the CNAME to your DNS and verify in Mailchimp.
SendGrid
- Go to Settings > Sender Authentication > Authenticate Your Domain
- Follow the wizard and select your DNS provider
- SendGrid provides three CNAME records: two for DKIM and one for SPF
The DKIM records look like:
Host: s1._domainkey
Type: CNAME
Value: s1.domainkey.u12345678.wl.sendgrid.net
Host: s2._domainkey
Type: CNAME
Value: s2.domainkey.u12345678.wl.sendgrid.net
Add both to your DNS and verify in SendGrid.
Adding DKIM records on Hostney
On Hostney, add the DKIM DNS records through Hosting > DNS Zone Editor in the control panel. Whether your email provider gives you TXT or CNAME records, add them with the exact host and value specified.
Since Hostney does not provide email services, your DKIM records will come from your email provider (Microsoft 365, Google Workspace, or whichever service handles your domain’s email).
Generating DKIM keys for your own mail server#
If you run your own mail server (Postfix, Exim, etc.) rather than using a hosted email provider, you generate the keys yourself.
Generate the key pair
openssl genrsa -out dkim_private.pem 2048
openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem
The first command generates a 2048-bit RSA private key. The second extracts the public key.
Format the public key for DNS
The public key file contains header and footer lines and is wrapped across multiple lines:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
...
-----END PUBLIC KEY-----
For the DNS record, remove the header, footer, and line breaks to get a single continuous string:
grep -v "PUBLIC KEY" dkim_public.pem | tr -d '\n'
Create the DNS TXT record
Choose a selector name (e.g.,
mail
or
default
) and create a TXT record:
Host: mail._domainkey
Type: TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
The
v=DKIM1
declares the DKIM version. The
k=rsa
specifies the key type. The
p=
is followed by the public key.
Configure the mail server
Install and configure OpenDKIM (for Postfix) or the equivalent signing software for your mail server. The configuration specifies:
- The path to the private key
- The selector name
- Which domains to sign
- Which headers to include in the signature
The specifics depend on your mail server software. For Postfix with OpenDKIM:
# /etc/opendkim.conf
Selector mail
KeyFile /etc/opendkim/keys/example.com/dkim_private.pem
Domain example.com
After configuring, restart the mail server and send a test email.
Testing DKIM#
Using the Hostney DMARC checker
Go to tools.hostney.com/dmarc and enter your domain. The tool checks your DKIM records (along with SPF and DMARC) and reports whether they are properly configured.
Using dig
Query the DKIM record directly:
dig +short TXT selector1._domainkey.example.com
Replace
selector1
with your actual selector. If the record exists and is properly formatted, you see the public key in the output.
Send a test email to Gmail
Send an email from your domain to a Gmail address. In Gmail, open the email and click the three dots menu, then Show original. Look for:
dkim=pass header.d=example.com header.s=selector1
If it says
dkim=pass
, DKIM is working. If it says
dkim=fail
, the signature verification failed — either the DNS record is wrong, the key does not match, or the message was modified in transit.
Check the email headers
Most email clients let you view full message headers. Look for the
Authentication-Results
header added by the receiving server:
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=selector1;
spf=pass (google.com: domain of user@example.com designates 203.0.113.50 as permitted sender);
This shows the result of both DKIM and SPF checks.
Key rotation#
DKIM private keys should be rotated periodically. If a private key is compromised, anyone with it can sign emails as your domain and pass DKIM verification. Regular rotation limits the window of exposure.
How to rotate DKIM keys
- Generate a new key pair
- Publish the new public key in DNS under a new selector (e.g.,
selector2if the current isselector1) - Wait for DNS propagation
- Configure the sending server to use the new private key and new selector
- Keep the old public key in DNS for 7-14 days (emails signed with the old key may still be in transit or in recipient queues)
- Remove the old DNS record after the transition period
Rotation with hosted providers
If you use Microsoft 365, Google Workspace, or another hosted provider, key rotation is handled by the provider. Microsoft 365 supports manual rotation through the Defender portal. Google Workspace generates new keys when you click “Generate new record” in the Admin console.
You still need to update DNS if the provider gives you new records, but the key generation and signing configuration are managed for you.
How often to rotate
There is no universal standard, but common recommendations:
- Quarterly (every 3 months) for high-security environments
- Annually for most organizations
- Immediately if you suspect a key compromise
If you use a 1024-bit key, rotate sooner and upgrade to 2048-bit. 1024-bit RSA keys are considered weak by modern standards and some receiving servers penalize them.
Common DKIM issues#
“DKIM record not found”
The DNS record does not exist or is not reachable. Common causes:
- The record was added to the wrong domain or subdomain
- The selector in the DNS host field does not match the selector the sending server uses
- DNS propagation has not completed (wait up to the TTL period, typically 1 hour)
- The record was added as the wrong type (A record instead of TXT, for example)
Verify the record exists:
dig +short TXT selector1._domainkey.yourdomain.com
If this returns nothing, the record is not in DNS.
“DKIM signature verification failed”
The signature is present but does not verify. Causes:
- Key mismatch. The public key in DNS does not correspond to the private key that signed the email. This happens after key rotation if the DNS record was not updated correctly.
- Message modification. Something altered the email after it was signed. Mailing list software that appends footers, virus scanners that modify content, or email gateways that rewrite headers can break DKIM signatures.
- Canonicalization issues. If the signing server uses “simple” canonicalization (strict byte-for-byte matching), even minor whitespace changes break the signature. “Relaxed” canonicalization tolerates minor formatting changes and is the recommended setting.
DNS TXT record too long
DKIM public keys, especially 2048-bit keys, can exceed the 255-character limit for a single DNS TXT string. The solution is to split the value into multiple quoted strings within a single TXT record:
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
"...remainder of the key..."
Most DNS providers handle this automatically when you paste the full value. If you see a “value too long” error, check whether your DNS provider requires manual splitting.
Multiple DKIM records
Unlike SPF (where you must have exactly one record), having multiple DKIM records is normal and expected. Each email provider uses a different selector, so each gets its own DNS record at a different hostname. Microsoft 365 uses
selector1._domainkey
and
selector2._domainkey
. Google uses
google._domainkey
. They do not conflict because they are separate DNS entries.
DKIM alone is not enough#
DKIM proves that an email was signed by someone with access to the private key for the specified domain. But it does not tell the receiving server what to do when verification fails. Should the email be rejected? Sent to spam? Accepted anyway?
That policy decision is what DMARC provides. DMARC also addresses a gap in both SPF and DKIM: neither one checks the “From” header that the recipient actually sees. An attacker can set the visible “From” address to your domain while using a completely different domain in the envelope sender (which SPF checks) and in the DKIM signature (which DKIM checks). DMARC adds “alignment” — it verifies that the domain in the visible “From” header matches the domains verified by SPF and DKIM.
For complete email authentication, you need all three:
- SPF verifies which servers can send email from your domain
- DKIM proves the email was not tampered with and was signed by an authorized sender
- DMARC ties them together with a policy and alignment checks
You can verify all three for your domain at tools.hostney.com/dmarc.