Home/Blog/Cybersecurity/DKIM Configuration Complete Guide: Key Generation, DNS Setup, and Best Practices
Cybersecurity

DKIM Configuration Complete Guide: Key Generation, DNS Setup, and Best Practices

Master DKIM email authentication with comprehensive coverage of key generation, DNS record setup, selector management, key rotation, and troubleshooting for major email platforms.

By Inventive Software
DKIM Configuration Complete Guide: Key Generation, DNS Setup, and Best Practices

DKIM Configuration Complete Guide

DKIM (DomainKeys Identified Mail) adds cryptographic signatures to your emails, allowing receivers to verify authenticity and detect tampering. This guide covers everything from key generation to production deployment.

How DKIM Works

┌─────────────────────────────────────────────────────────────────────────────┐
│                         DKIM SIGNING PROCESS                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  SENDING SERVER                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                                                                      │   │
│  │   1. Compose Email                                                   │   │
│  │      ┌────────────────────────────────────────────────────────┐     │   │
│  │      │ From: [email protected]                               │     │   │
│  │      │ To: [email protected]                                │     │   │
│  │      │ Subject: Important Update                              │     │   │
│  │      │ Date: Mon, 08 Jan 2025 10:00:00 -0000                 │     │   │
│  │      │                                                        │     │   │
│  │      │ Hello, this is the message body...                    │     │   │
│  │      └────────────────────────────────────────────────────────┘     │   │
│  │                              │                                       │   │
│  │                              ▼                                       │   │
│  │   2. Create Hash of Headers + Body                                   │   │
│  │      ┌────────────────────────────────────────────────────────┐     │   │
│  │      │ Headers to sign: from, to, subject, date               │     │   │
│  │      │ Body hash: SHA-256(body) = bh=47DEQpj8HBSa...         │     │   │
│  │      └────────────────────────────────────────────────────────┘     │   │
│  │                              │                                       │   │
│  │                              ▼                                       │   │
│  │   3. Sign with Private Key                                           │   │
│  │      ┌────────────────────┐   ┌───────────────────────────────┐     │   │
│  │      │    PRIVATE KEY     │──▶│  Signature: b=dzdVyOf...     │     │   │
│  │      │    (kept secret)   │   │                               │     │   │
│  │      └────────────────────┘   └───────────────────────────────┘     │   │
│  │                              │                                       │   │
│  │                              ▼                                       │   │
│  │   4. Add DKIM-Signature Header                                       │   │
│  │      ┌────────────────────────────────────────────────────────┐     │   │
│  │      │ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; │     │   │
│  │      │  d=example.com; s=selector;                            │     │   │
│  │      │  h=from:to:subject:date;                               │     │   │
│  │      │  bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;     │     │   │
│  │      │  b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD...  │     │   │
│  │      └────────────────────────────────────────────────────────┘     │   │
│  │                                                                      │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                      │                                      │
│                                      ▼                                      │
│  RECEIVING SERVER                                                           │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                                                                      │   │
│  │   5. Extract Signature Info                                          │   │
│  │      d=example.com  s=selector  a=rsa-sha256                        │   │
│  │                              │                                       │   │
│  │                              ▼                                       │   │
│  │   6. DNS Query for Public Key                                        │   │
│  │      ┌────────────────────────────────────────────────────────┐     │   │
│  │      │ Query: selector._domainkey.example.com TXT             │     │   │
│  │      │ Response: "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG..."     │     │   │
│  │      └────────────────────────────────────────────────────────┘     │   │
│  │                              │                                       │   │
│  │                              ▼                                       │   │
│  │   7. Verify Signature                                                │   │
│  │      ┌────────────────────┐   ┌───────────────────────────────┐     │   │
│  │      │    PUBLIC KEY      │──▶│  Decrypt signature           │     │   │
│  │      │  (from DNS)        │   │  Compare to computed hash    │     │   │
│  │      └────────────────────┘   └───────────────────────────────┘     │   │
│  │                              │                                       │   │
│  │                    ┌─────────┴─────────┐                            │   │
│  │                    ▼                   ▼                            │   │
│  │            ┌─────────────┐     ┌─────────────┐                      │   │
│  │            │    PASS     │     │    FAIL     │                      │   │
│  │            │ (Authentic) │     │ (Modified   │                      │   │
│  │            │             │     │  or Forged) │                      │   │
│  │            └─────────────┘     └─────────────┘                      │   │
│  │                                                                      │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

DKIM Record Structure

┌─────────────────────────────────────────────────────────────────────────────┐
│                         DKIM DNS RECORD                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Record Name: selector._domainkey.example.com                               │
│                   │          │          │                                   │
│                   │          │          └── Your domain                     │
│                   │          └── Fixed subdomain (always _domainkey)        │
│                   └── Your chosen selector name                             │
│                                                                             │
│  Record Type: TXT                                                           │
│                                                                             │
│  Record Value:                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...  │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  Tag Breakdown:                                                             │
│  ┌──────────┬──────────┬────────────────────────────────────────────────┐  │
│  │   Tag    │ Required │  Description                                   │  │
│  ├──────────┼──────────┼────────────────────────────────────────────────┤  │
│  │ v=DKIM1  │   Yes*   │  Version (always DKIM1)                       │  │
│  │ k=rsa    │   No     │  Key type (rsa default, ed25519 emerging)     │  │
│  │ p=...    │   Yes    │  Public key (base64 encoded)                  │  │
│  │ t=s      │   No     │  Testing mode: s=strict, y=testing            │  │
│  │ h=sha256 │   No     │  Hash algorithm                               │  │
│  │ s=email  │   No     │  Service type: * or email                     │  │
│  │ n=...    │   No     │  Notes (human-readable)                       │  │
│  └──────────┴──────────┴────────────────────────────────────────────────┘  │
│  * Technically optional but recommended                                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Generating DKIM Keys

Using OpenSSL (Standard Method)

# Generate 2048-bit RSA private key
openssl genrsa -out dkim_private.key 2048

# Extract public key from private key
openssl rsa -in dkim_private.key -pubout -out dkim_public.key

# View the public key (for DNS record)
cat dkim_public.key

Output:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDn4PTAMt5+s6M
3XvPr5L7F5L6hQKMVJjGE8nG3R5F5OKUvM6PTdVLgO4yK4HG4Z5vMQ8dL6R5+s/y
M3n3f3H3h3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3
f3L3h3H3f3L3h3QIDAQAB
-----END PUBLIC KEY-----

Format for DNS Record

Remove headers and line breaks to create the DNS value:

# Extract just the key content (remove headers, join lines)
sed -e '/^-/d' dkim_public.key | tr -d '\n'

DNS TXT Record Value:

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDn4PTAMt5+s6M3XvPr5L7F5L6hQKMVJjGE8nG3R5F5OKUvM6PTdVLgO4yK4HG4Z5vMQ8dL6R5+s/yM3n3f3H3h3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3H3f3L3h3QIDAQAB

Generating 4096-bit Keys (High Security)

# Generate larger key (may need to split in DNS)
openssl genrsa -out dkim_private_4096.key 4096
openssl rsa -in dkim_private_4096.key -pubout -out dkim_public_4096.key

Note: 4096-bit keys exceed DNS TXT record limits (255 chars per string). Most DNS providers handle splitting automatically, but verify your provider supports this.

Ed25519 Keys (Emerging Standard)

# Generate Ed25519 key pair (smaller, faster, equally secure)
openssl genpkey -algorithm ED25519 -out dkim_ed25519_private.key
openssl pkey -in dkim_ed25519_private.key -pubout -out dkim_ed25519_public.key

DNS Record for Ed25519:

v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=

Platform-Specific Configuration

Google Workspace

Admin Console Setup:

  1. Go to Admin ConsoleAppsGoogle WorkspaceGmail
  2. Click Authenticate email
  3. Select your domain
  4. Click Generate new record
  5. Select 2048-bit key length
  6. Note the selector (e.g., google)
  7. Copy the TXT record value

DNS Record:

Host: google._domainkey
Type: TXT
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG...
  1. Wait 24-48 hours for propagation
  2. Return to Admin Console and click Start authentication

Microsoft 365

Exchange Admin Center Setup:

  1. Go to Exchange Admin CenterMail flowRules
  2. Or use PowerShell:
# Connect to Exchange Online
Connect-ExchangeOnline

# Create DKIM signing config
New-DkimSigningConfig -DomainName example.com -Enabled $true

# Get DKIM CNAME records
Get-DkimSigningConfig -Identity example.com | Format-List Selector1CNAME, Selector2CNAME

DNS Records (CNAME):

Host: selector1._domainkey
Type: CNAME
Value: selector1-example-com._domainkey.example.onmicrosoft.com

Host: selector2._domainkey
Type: CNAME
Value: selector2-example-com._domainkey.example.onmicrosoft.com

Postfix (Linux Mail Server)

Install OpenDKIM:

# Ubuntu/Debian
sudo apt-get install opendkim opendkim-tools

# CentOS/RHEL
sudo yum install opendkim opendkim-tools

Generate Keys:

# Create key directory
sudo mkdir -p /etc/opendkim/keys/example.com

# Generate key pair
sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail -v

# Set permissions
sudo chown -R opendkim:opendkim /etc/opendkim/keys
sudo chmod 600 /etc/opendkim/keys/example.com/mail.private

Configure OpenDKIM (/etc/opendkim.conf):

# Basic settings
Syslog                  yes
UMask                   007
Socket                  local:/run/opendkim/opendkim.sock

# Domain settings
Domain                  example.com
KeyFile                 /etc/opendkim/keys/example.com/mail.private
Selector                mail

# Signing options
Canonicalization        relaxed/relaxed
Mode                    sv
SubDomains              no

# Additional settings
AutoRestart             yes
AutoRestartRate         10/1M
Background              yes
DNSTimeout              5
SignatureAlgorithm      rsa-sha256

Configure Key Table (/etc/opendkim/KeyTable):

mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private

Configure Signing Table (/etc/opendkim/SigningTable):

*@example.com mail._domainkey.example.com

Configure Postfix (/etc/postfix/main.cf):

# DKIM signing via OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/run/opendkim/opendkim.sock
non_smtpd_milters = local:/run/opendkim/opendkim.sock

Start Services:

sudo systemctl enable opendkim
sudo systemctl start opendkim
sudo systemctl restart postfix

Amazon SES

Enable DKIM (AWS Console):

  1. Go to SES ConsoleVerified Identities
  2. Select your domain
  3. Go to Authentication tab → DKIM
  4. Click Generate DKIM tokens
  5. Add the provided CNAME records to DNS

DNS Records (CNAME):

Host: xxxxxxxx._domainkey
Type: CNAME
Value: xxxxxxxx.dkim.amazonses.com

Host: yyyyyyyy._domainkey
Type: CNAME
Value: yyyyyyyy.dkim.amazonses.com

Host: zzzzzzzz._domainkey
Type: CNAME
Value: zzzzzzzz.dkim.amazonses.com

Using AWS CLI:

# Enable DKIM for a verified domain
aws ses verify-domain-dkim --domain example.com

# Get DKIM tokens
aws ses get-identity-dkim-attributes --identities example.com

SendGrid

Enable DKIM (Dashboard):

  1. Go to SettingsSender Authentication
  2. Click Authenticate Your Domain
  3. Select DNS host and enter domain
  4. Add the provided DNS records

DNS Records:

Host: s1._domainkey
Type: CNAME
Value: s1.domainkey.uXXXXXX.wlXXX.sendgrid.net

Host: s2._domainkey
Type: CNAME
Value: s2.domainkey.uXXXXXX.wlXXX.sendgrid.net

DKIM Signature Header Explained

┌─────────────────────────────────────────────────────────────────────────────┐
│                    DKIM-SIGNATURE HEADER ANATOMY                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;                     │
│   d=example.com; s=mail; t=1704700000;                                      │
│   h=from:to:subject:date:message-id;                                       │
│   bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;                         │
│   b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZ...                │
│                                                                             │
│  TAG BREAKDOWN:                                                             │
│  ┌──────┬────────────────────────────────────────────────────────────────┐ │
│  │ v=1  │ Signature version (always 1)                                   │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ a=   │ Algorithm: rsa-sha256 (recommended) or rsa-sha1               │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ c=   │ Canonicalization: header/body (relaxed/relaxed recommended)   │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ d=   │ Signing domain (must match From header for DMARC alignment)   │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ s=   │ Selector (used to lookup public key in DNS)                   │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ t=   │ Timestamp (Unix epoch when signed)                            │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ x=   │ Expiration (optional, Unix epoch when signature expires)      │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ h=   │ Headers included in signature (order matters)                 │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ bh=  │ Body hash (SHA-256 hash of canonicalized body, base64)       │ │
│  ├──────┼────────────────────────────────────────────────────────────────┤ │
│  │ b=   │ Signature (RSA signature of header hash, base64)             │ │
│  └──────┴────────────────────────────────────────────────────────────────┘ │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Canonicalization Explained

┌─────────────────────────────────────────────────────────────────────────────┐
│                    CANONICALIZATION OPTIONS                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Format: c=header/body                                                      │
│                                                                             │
│  SIMPLE CANONICALIZATION (strict)                                           │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ • No changes to headers (except trailing CRLF)                        │ │
│  │ • Body: trailing whitespace removed, empty lines at end removed       │ │
│  │ • Signature fails if ANY modification occurs in transit               │ │
│  │ • NOT recommended (forwarding often breaks signature)                 │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  RELAXED CANONICALIZATION (recommended)                                     │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ Headers:                                                              │ │
│  │ • Unfold multi-line headers                                          │ │
│  │ • Convert names to lowercase                                          │ │
│  │ • Collapse multiple spaces to single space                            │ │
│  │ • Remove trailing whitespace                                          │ │
│  │                                                                        │ │
│  │ Body:                                                                  │ │
│  │ • Collapse multiple spaces to single space                            │ │
│  │ • Remove trailing whitespace from lines                               │ │
│  │ • Remove empty lines at end                                           │ │
│  │                                                                        │ │
│  │ Survives minor modifications by mail relays                           │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  EXAMPLE TRANSFORMATION (relaxed):                                          │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ Original:                                                             │ │
│  │   Subject: Test   Email                                              │ │
│  │            (continued)                                                │ │
│  │                                                                        │ │
│  │ Canonicalized:                                                        │ │
│  │   subject: Test Email (continued)                                    │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  RECOMMENDATION: Always use c=relaxed/relaxed                               │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Key Rotation

Rotation Process

┌─────────────────────────────────────────────────────────────────────────────┐
│                      DKIM KEY ROTATION PROCESS                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Day 0: Prepare New Key                                                     │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ 1. Generate new key pair with NEW selector                            │ │
│  │    openssl genrsa -out new_private.key 2048                          │ │
│  │                                                                        │ │
│  │ 2. Choose new selector name (e.g., mail2024, s2, key2)               │ │
│  │                                                                        │ │
│  │ DNS State:                                                            │ │
│  │   mail._domainkey.example.com    → OLD public key (active)           │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  Day 1: Publish New Key                                                     │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ 3. Add new public key to DNS (keep old key)                          │ │
│  │                                                                        │ │
│  │ DNS State:                                                            │ │
│  │   mail._domainkey.example.com     → OLD public key (active)          │ │
│  │   mail2024._domainkey.example.com → NEW public key (ready)           │ │
│  │                                                                        │ │
│  │ 4. Wait for DNS propagation (24-48 hours)                            │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  Day 3: Switch to New Key                                                   │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ 5. Update mail server to sign with new selector/key                   │ │
│  │                                                                        │ │
│  │ Mail Server Config:                                                   │ │
│  │   Selector: mail2024 (was: mail)                                      │ │
│  │   KeyFile: /path/to/new_private.key                                  │ │
│  │                                                                        │ │
│  │ DNS State:                                                            │ │
│  │   mail._domainkey.example.com     → OLD public key (for emails       │ │
│  │                                      still in transit/queues)        │ │
│  │   mail2024._domainkey.example.com → NEW public key (active)          │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  Day 33: Remove Old Key                                                     │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ 6. Remove old public key from DNS (after 30+ days)                    │ │
│  │                                                                        │ │
│  │ DNS State:                                                            │ │
│  │   mail2024._domainkey.example.com → NEW public key (only key)        │ │
│  │                                                                        │ │
│  │ 7. Archive/destroy old private key                                    │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Rotation Script

#!/bin/bash
# DKIM key rotation script

DOMAIN="example.com"
OLD_SELECTOR="mail"
NEW_SELECTOR="mail$(date +%Y)"
KEY_DIR="/etc/opendkim/keys/${DOMAIN}"

# Generate new key
opendkim-genkey -b 2048 -d ${DOMAIN} -D ${KEY_DIR} -s ${NEW_SELECTOR} -v

# Display new DNS record
echo "Add this DNS record:"
cat ${KEY_DIR}/${NEW_SELECTOR}.txt

# After DNS propagation, update OpenDKIM config
echo ""
echo "After DNS propagates, update these files:"
echo "KeyTable: ${NEW_SELECTOR}._domainkey.${DOMAIN} ${DOMAIN}:${NEW_SELECTOR}:${KEY_DIR}/${NEW_SELECTOR}.private"
echo "Then restart: systemctl restart opendkim"

Testing and Verification

Verify DNS Record

# Using dig
dig +short TXT mail._domainkey.example.com

# Using nslookup
nslookup -type=TXT mail._domainkey.example.com

# Using host
host -t TXT mail._domainkey.example.com

Test with Email

Send a test email to a major provider (Gmail, Outlook) and check headers:

Authentication-Results: mx.google.com;
       dkim=pass [email protected] header.s=mail header.b=dzdVyOf;
       spf=pass (google.com: domain of [email protected] designates ...
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

Online Testing Tools

  1. mail-tester.com - Send email, get detailed report
  2. dkimvalidator.com - Check DNS record format
  3. mxtoolbox.com/dkim.aspx - DNS lookup and validation

Command-Line Testing

# Test DKIM signing (Postfix + OpenDKIM)
echo "Test message" | mail -s "DKIM Test" [email protected]

# Check OpenDKIM status
systemctl status opendkim

# View OpenDKIM logs
journalctl -u opendkim -f

# Test with opendkim-testkey
opendkim-testkey -d example.com -s mail -vvv

Troubleshooting

Common Errors

ErrorCauseSolution
dkim=neutral (no key)DNS record missing or not propagatedCheck DNS, wait for propagation
dkim=fail (bad signature)Key mismatch or message modifiedVerify key pair match, check intermediaries
dkim=fail (body hash)Body modified in transitUse relaxed canonicalization
dkim=temperrorDNS timeoutCheck DNS server availability
dkim=permerrorMalformed DNS recordFix syntax errors in TXT record

Debug Checklist

┌─────────────────────────────────────────────────────────────────────────────┐
│                      DKIM TROUBLESHOOTING CHECKLIST                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  DNS Issues                                                                 │
│  [ ] TXT record exists at selector._domainkey.domain.com                   │
│  [ ] Record starts with v=DKIM1                                            │
│  [ ] Public key (p=) is present and correctly formatted                    │
│  [ ] No extra whitespace or line breaks in record                          │
│  [ ] DNS has propagated (check from multiple locations)                    │
│                                                                             │
│  Key Issues                                                                 │
│  [ ] Private key matches public key in DNS                                 │
│  [ ] Private key file has correct permissions (600)                        │
│  [ ] Key pair was generated correctly (not corrupted)                      │
│  [ ] Using supported key type (RSA or Ed25519)                             │
│                                                                             │
│  Configuration Issues                                                       │
│  [ ] Selector in config matches DNS record name                            │
│  [ ] Domain in config matches signing domain                               │
│  [ ] Mail server is using the signing milter/filter                        │
│  [ ] Signing service is running and accessible                             │
│                                                                             │
│  Signature Issues                                                           │
│  [ ] DKIM-Signature header is being added to outgoing mail                 │
│  [ ] Signed headers include From, To, Subject, Date                        │
│  [ ] Using relaxed/relaxed canonicalization                                │
│  [ ] Body hash (bh=) is being computed correctly                           │
│                                                                             │
│  Delivery Issues                                                            │
│  [ ] No intermediaries modifying signed content                            │
│  [ ] Mailing lists preserving DKIM signature                               │
│  [ ] Forwarding not breaking signature                                      │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Best Practices

Security Recommendations

  1. Use 2048-bit RSA keys minimum - 1024-bit is deprecated
  2. Rotate keys annually - More frequently for high-security
  3. Protect private keys - Restrict file permissions, consider HSM
  4. Use relaxed canonicalization - Better survivability
  5. Sign important headers - from, to, subject, date, message-id
  6. Monitor DMARC reports - Detect misconfigurations early

Selector Naming Conventions

ConventionExampleUse Case
Service-basedgoogle, sendgridThird-party email services
Date-based2024q1, mail2024Key rotation tracking
Sequentials1, s2, key1Simple rotation
Environmentprod, stagingMultiple environments

Multiple Sender Configuration

┌─────────────────────────────────────────────────────────────────────────────┐
│                    MULTI-SENDER DKIM SETUP                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  DNS Records:                                                               │
│  ┌───────────────────────────────────────────────────────────────────────┐ │
│  │ google._domainkey.example.com      → Google Workspace public key      │ │
│  │ sendgrid._domainkey.example.com    → SendGrid public key              │ │
│  │ mail._domainkey.example.com        → Your mail server public key      │ │
│  │ mailchimp._domainkey.example.com   → Mailchimp public key             │ │
│  └───────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│  Each service signs with its own selector, all for example.com             │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Tools

Need Expert Cybersecurity Guidance?

Our team of security experts is ready to help protect your business from evolving threats.