DKIM: Proper Email Signing and Key Rotation Every 6-12 Months
DKIM cryptographically authenticates your emails. Use 2048-bit RSA or Ed25519, multiple selectors, and periodic rotation to limit damage in case of compromise.
In Short
DKIM (DomainKeys Identified Mail, RFC 6376) adds a cryptographic signature to every outgoing email, signed with a private key held by your MTA. The public key is published in DNS under a selector. The receiver (Gmail, Outlook365) verifies the signature and — if valid and matching the domain in From: — confirms that the email was not modified in transit and originates from an authorized entity.
In 2026, DKIM is a de facto requirement: Gmail and Yahoo have mandated since February 2024 that all bulk senders (>5000 messages/day to their accounts) must have functional SPF + DKIM + DMARC — otherwise emails are rejected or flagged as spam. For any company with newsletters, automated invoices, or transactional notifications, correct DKIM is the difference between 95%+ deliverability and 60%.
The often ignored aspect: the DKIM key is not set-and-forget. Like any cryptographic key, it must be rotated periodically. A compromised key (hacked server, exposed backup, former employee with access) allows an attacker to sign legitimate emails on your behalf for months until you notice.
Concrete Attacks Prevented
Scenario 1 — Content Tampering in Transit
An on-path attacker (ISP network, datacenter) intercepts an email with an attached PDF invoice. They modify the IBAN in the PDF before the email reaches the client. Without DKIM, the modification is undetectable. With DKIM (signature on Subject:, From:, Date: and body hash), any modification invalidates the signature — the receiver rejects or marks it as suspicious.
Scenario 2 — Replay with Altered Content (DKIM Key Compromise)
A company’s 1024-bit DKIM key was cracked in 2012 (public Zachary Harris case). The attacker sent a validly signed email to Google, claiming to be the company CEO. 1024-bit RSA keys are technically breakable with moderate cloud resources (~$75,000 USD in 2025) — a minimum of 2048-bit is mandatory.
Scenario 3 — Former Employee with Private Key Access
The DevOps engineer fired in 2024 copied /etc/postfix/dkim/private.key before leaving. For 8 months, until the new team rotated the key (after reading this article), the former employee could have signed valid emails to any recipient — impersonating the CEO, accounting, etc. Mandatory rotation every 6-12 months limits this window.
Business Impact
| Aspect | 1024-bit Key, No Rotation | 2048-bit Key + 6-Month Rotation |
|---|---|---|
| Cost to compromise key (2026) | ~$75,000 USD (factorization) | >10^60 years (computationally infeasible) |
| Compromise window post-leak | infinite | max 6 months |
| Gmail/Yahoo bulk deliverability | rejected (since 2024) | accepted |
| DORA / NIS2 Audit | finding | covered |
| Periodic rotation cost | — | ~1h/operation, 2x/year |
Implementation — Step-by-Step Guide
Step 1 — Generate 2048-bit DKIM Key (or Ed25519)
For OpenDKIM / Postfix:
# RSA 2048-bit (universally compatible)
opendkim-genkey -b 2048 -d firma.ro -s 2026a -v
# Or Ed25519 (modern, fast, majority supported since 2024)
opendkim-genkey -t ed25519 -d firma.ro -s 2026a-ed -v
Output: two files — 2026a.private (keep only on MTA, mode 0600, root) and 2026a.txt (DNS TXT record).
Do not use 1024-bit. RFC 8301 explicitly marks 1024 as weak. For retro-compatibility with old MTAs that do not support Ed25519, publish both selectors (RSA 2048 + Ed25519) — the receiver chooses.
Step 2 — Publish Public Key in DNS
2026a._domainkey.firma.ro. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCA..."
Watch out for TXT record length — over 255 characters must be split into segments; most DNS providers handle this automatically if you enter it on a single line in the UI.
Verification:
dig +short TXT 2026a._domainkey.firma.ro
opendkim-testkey -d firma.ro -s 2026a -k /etc/opendkim/keys/firma.ro/2026a.private -vvv
Step 3 — Configure MTA to Sign with New Selector
Postfix + OpenDKIM (/etc/opendkim/key.table):
2026a._domainkey.firma.ro firma.ro:2026a:/etc/opendkim/keys/firma.ro/2026a.private
Reload OpenDKIM. Send a test email to check-auth@verifier.port25.com — the automated response confirms a valid signature.
Step 4 — Rotation Procedure (Every 6-12 Months)
Rotation is performed without downtime via selector overlap:
- T-30 days: generate new selector (
2026b), publish TXT, but do not activate signing yet. - T-0: switch MTA to sign with
2026b. Leave2026ain DNS. - T+7 days: if no issues, delete
2026afrom DNS (implicit revoke). - T+8 days: delete private key
2026a.privatefrom MTA + backups.
Never delete the old key immediately after rotation — emails signed before the switch are still in transit; receivers may attempt verification later.
Step 5 — Automation + Monitoring
Add an alert (cron or Zabbix) that warns you at 5.5 months from generation:
# Check key creation date and warn at 5.5 months
find /etc/opendkim/keys/ -name "*.private" -mtime +165 -exec echo "ROTATION REQUIRED: {}" \;
Log issued DKIM signatures (Postfix header_checks or Graylog) — during an audit, this demonstrates that signing was active continuously.
Common Confusions
“The default selector default is sufficient.” — Dangerous. During rotation you cannot perform overlap; you are forced to accept downtime or use only 1 permanent key (anti-pattern). Use dataframe-style selectors: 2026a, 2026b, etc.
“Ed25519 is not universally supported.” — This was true in 2018. Since 2024, Gmail, Outlook365, Yahoo, and ProtonMail all verify Ed25519. Only a few legacy on-prem MTAs do not — for those, keep RSA in parallel.
“DKIM prevents forwarding.” — Partially true. Forwarding with modification (mailing list adding a footer) breaks the signature. Solution: ARC (Authenticated Received Chain, RFC 8617) or re-DKIM at the mailing list. Clean forwarding (server-side, without rewrite) keeps the signature intact.
“Private key in Git is ok if the repo is private.” — Absolutely not. Compromised Git repo = compromised key for months. The private key lives only on the MTA, generated with umask 077, without unencrypted backups.
Check Now
ARTEMIS automatically checks: DKIM presence, key size (warning <2048-bit), alignment with DMARC, detectable expiration, and 30+ other email-security checks.
🔗 Complementary CAI Technology Solutions
- ARTEMIS — Technical DKIM scanning (all observable selectors) + key size + alignment + DMARC integration.
- Lexnomia — Auditor-grade compliance evaluation for NIS2 / GDPR / DORA with official reports.
- BeLegal with SandboxAI — Free 5-minute compliance check.
- Auditope — Holistic web audit (SEO + AI search + GDPR + security).
- AriaUnited — European funds consultancy for cryptographic hardening projects.
Questions? tehnic@caitech.ro