← RFC Reference

RFC 8463: Ed25519 for DKIM Signatures

Standards Track Email Authentication Published September 2018
ELI5: DKIM originally used RSA keys — the same type of keys that protect most of the web. But RSA keys are bulky: a 2048-bit public key takes up 400+ characters in a DNS TXT record. Ed25519 is a newer, sleeker lock that’s just as strong with a key that fits in 44 characters. Smaller key, faster verification, same trust — that’s what RFC 8463 brings to DKIM.

Why This Exists

DKIM (RFC 6376) originally specified only RSA for signatures. RSA has served well, but it comes with costs:

Ed25519 (Edwards-curve Digital Signature Algorithm using Curve25519) solves all three problems. Its 256-bit keys provide security equivalent to roughly 3072-bit RSA, the public key is only 32 bytes (44 characters Base64), and verification is significantly faster.

How It Works

Signing with Ed25519

The signing process is identical to standard DKIM, with two changes: the a= tag uses ed25519-sha256 instead of rsa-sha256, and the private key is an Ed25519 key instead of RSA.

  1. Canonicalize headers and body per RFC 6376 rules.
  2. Compute the SHA-256 hash of the canonicalized body (bh= tag).
  3. Compute the SHA-256 hash of the signed headers plus body hash.
  4. Sign the header hash using the Ed25519 private key.
  5. Emit the DKIM-Signature header with a=ed25519-sha256.

Example: Ed25519 DKIM-Signature

DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=example.com; s=ed202601; h=from:to:subject:date:message-id:mime-version:content-type; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=Tg2ByC4LSy9F1F6xAQchD8JFh6kYH7aKQjO6Sn7XIkfJVOzv8RBVOzv8QjO6S n7XIkfJV==

DNS Public Key Record

The key record uses k=ed25519 and the public key is dramatically smaller than RSA:

; Ed25519 DKIM key — note how compact the p= value is ed202601._domainkey.example.com. IN TXT "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=" ; Compare with RSA 2048-bit key — much larger rsa202601._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2UMfREvlgajdSp3jv1oI...truncated (392 characters)..."

Dual Signing: The Recommended Approach

Not all receivers support Ed25519 yet. RFC 8463 recommends dual signing: apply both an RSA signature and an Ed25519 signature to each message. Receivers that understand Ed25519 can verify the stronger signature; those that don't will fall back to the RSA signature.

; A message with two DKIM-Signature headers: DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=example.com; s=ed202601; h=from:to:subject:date:message-id; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=Tg2ByC4LSy9F1F6xAQchD8JFh6kYH7aK... DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=rsa202601; h=from:to:subject:date:message-id; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=LjIEJLNOTAREALh8gAiGVQOr3K7qO6Sn7XIkfJV...

Both signatures share the same bh= (body hash) and h= (signed headers) but use different selectors pointing to different key types in DNS.

Key Technical Details

Key Size Comparison

Property RSA-2048 Ed25519
Security level (bits) ~112 ~128
Public key size (Base64) ~392 characters 44 characters
Signature size (Base64) ~344 characters 88 characters
Signing speed Moderate Fast
Verification speed Fast Very fast
DNS TXT record size Tight fit, may need splitting Easily fits in a single string

Key Generation

# Generate an Ed25519 key pair using OpenSSL 1.1.1+ openssl genpkey -algorithm Ed25519 -out ed25519_private.pem # Extract the public key openssl pkey -in ed25519_private.pem -pubout -out ed25519_public.pem # Get the raw Base64 public key for DNS (strip PEM headers) openssl pkey -in ed25519_private.pem -pubout -outform DER | tail -c 32 | base64 11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo= # Publish in DNS as: # ed202601._domainkey.example.com. IN TXT "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="

DNS Record Format

The only change from a standard DKIM key record is k=ed25519. All other tags (v=, p=, t=, etc.) work the same as RSA key records:

; Required tags v=DKIM1 ; version (always DKIM1) k=ed25519 ; key type (was "rsa" by default) p=<base64> ; 44-character public key ; Optional tags (same as RSA) t=s ; strict mode: d= must exactly match From domain t=y ; testing mode: receivers should not treat failures as definitive

Receiver Behavior

When a receiver encounters a=ed25519-sha256 in a DKIM-Signature:

  1. Look up the DNS key record for the selector.
  2. Confirm k=ed25519 in the key record.
  3. Decode the 32-byte public key from the p= tag.
  4. Verify the Ed25519 signature against the SHA-256 hash of the canonicalized headers.

If the receiver does not support Ed25519, it treats the signature as unverifiable (not a hard failure) and moves on to any other DKIM-Signature headers on the message.

Common Mistakes

Deliverability Impact

Related RFCs