HackBlue

Tools · Email security · 02 / 18

DKIM: selectors, public keys, and verifying a signature yourself

Understand how DKIM signs headers and body, find a sender’s public key through its selector, read the tags in a DKIM-Signature header, and plan key rotation.

9 min read · practice only with authorization

How DKIM works

The sending system hashes the message body and a chosen list of headers, signs the result with a private key, and adds a DKIM-Signature header. The receiver reads the d= domain and s= selector, fetches the public key from selector._domainkey.domain in DNS, and verifies the signature. A pass proves the signed parts were not altered and that the signing domain authorized the message.

Reading the signature header

Key tags are v (version), a (algorithm, usually rsa-sha256), d (signing domain), s (selector), h (signed headers), bh (body hash), b (signature), and c (canonicalization such as relaxed/relaxed). The From header must be in h. Relaxed canonicalization tolerates whitespace changes in transit; simple does not.

Snippet
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.org;
 s=mail2026; h=from:to:subject:date:message-id; bh=2jUSOH9N...=;
 b=Kq3vX...

dig +short TXT mail2026._domainkey.example.org
"v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."

Lab: verify a message you received

Save a newsletter or notification you received as a raw .eml file. Read its DKIM-Signature to find d= and s=, look up the public key with dig, and then verify it with the dkimpy package. Edit one character in the Subject in a copy and verify again to see the signature fail, which shows exactly what DKIM protects.

Snippet
python3 -m pip install --user dkimpy
dkimverify < message.eml        # expect: signature ok
sed 's/^Subject: /Subject: X/' message.eml > edited.eml
dkimverify < edited.eml         # expect: signature verification failed

Key management

Use 2048-bit RSA keys where your DNS provider supports long TXT records, and rotate keys periodically by publishing a new selector, switching signing to it, and removing the old record after messages in flight have been delivered. Each third-party sender should sign with its own selector so you can revoke one without affecting others.

  • 2048-bit keys
  • One selector per sending service
  • Rotate by adding a new selector first
  • Remove old selectors after a grace period

Diagram

Verifying a DKIM signature

Selector and domain point the receiver at the right key.

DKIMDNSverify

Header

DKIM-Signature: d=example.org; s=mail2026; h=from:to:subject
tags parsed

DNS

TXT mail2026._domainkey.example.org
v=DKIM1; k=rsa; p=MIIB...

Verify

recompute body hash and header hash
signature ok

Check yourself

1. Where does a receiver find the DKIM public key?

2. Which header must be included in the signed header list?

3. What is the safe first step in rotating a DKIM key?