DomainKeys Identified Mail (DKIM) Signatures
obsoletes
- rfc-4871 — DomainKeys Identified Mail (DKIM) Signatures
- rfc-5672 — RFC 4871 DomainKeys Identified Mail (DKIM) Signatures -- Update
updated by
- rfc-8301 — Cryptographic Algorithm and Key Usage Update to DomainKeys Identified Mail (DKIM)
- rfc-8463 — A New Cryptographic Signature Method for DomainKeys Identified Mail (DKIM)
- rfc-8553 — DNS Attrleaf Changes: Fixing Specifications That Use Underscored Node Names
- rfc-8616 — Email Authentication for Internationalized Mail
also
- std-76
Extracted elements (28)
DKIM uses DNS directly for public key distribution rather than a certificate authority infrastructure. This avoids dependency on trusted third parties, requires no new protocols, and allows anyone to validate a signature by querying the signing domain directly.
The body length limit (l= tag) was provided because mailing lists commonly append trailers to messages. This allows a Signer to cover only the original body and allows Verifiers to accept messages with extraneous appended data as a matter of policy, though this introduces security risks described in Section 8.2.
The signing identity (SDID/AUID) is not required to match any particular header field such as From. This is intentional because of the broad methods of interpretation by recipient mail systems, and trust binding between the SDID and other identifiers is left to higher-level assessor policy.
Signing existing DKIM-Signature header fields is legal but inadvisable because intermediaries that do not treat DKIM-Signature as a trace header field may reorder them, breaking such signatures. Signers SHOULD NOT remove any DKIM-Signature header fields from messages they are signing.
All DKIM implementations MUST support the DNS TXT RR binding for key storage. The DKIM key is located at selector._domainkey.domain (e.g., 'foo.bar._domainkey.example.com').
In the DKIM key record, if the 's' flag is present in the t= tag, the domain of the AUID (i=) MUST be exactly the same as the SDID (d=) and MUST NOT be a subdomain. Use of the 's' flag is RECOMMENDED unless subdomaining is required.
Signers MUST implement and SHOULD sign using rsa-sha256. Verifiers MUST implement both rsa-sha1 and rsa-sha256.
Signers MUST use RSA keys of at least 1024 bits for long-lived keys. Verifiers MUST be able to validate signatures with keys ranging from 512 bits to 2048 bits, and MAY validate larger keys.
Tags with duplicate names MUST NOT occur within a single tag-list; if a tag name occurs more than once, the entire tag-list is invalid. Tags MUST be interpreted in a case-sensitive manner.
The DKIM-Signature header field MUST include the following required tags: v= (version), a= (algorithm), b= (signature data), bh= (body hash), d= (SDID), h= (signed header fields), and s= (selector).
The 'relaxed' header canonicalization algorithm MUST: convert header field names to lowercase, unfold continuation lines, convert WSP sequences to single SP, delete trailing WSP, and delete WSP surrounding the colon separator.
The Signer MUST sign the message as it is expected to be received by the Verifier. Bare CR or LF characters MUST be converted to CRLF before signing.
The Signer/Verifier MUST compute two hashes: one over the canonicalized body (stored in bh=) and one over the selected header fields including the DKIM-Signature itself (with b= treated as empty string).
Upon successfully verifying the signature, a receive-side DKIM Verifier MUST communicate the Signing Domain Identifier (d=) to a consuming Identity Assessor module and MAY communicate the AUID (i=) if present.
Verifiers MUST ignore any signatures using algorithms that they do not implement. Verifiers SHOULD continue checking signatures until one successfully verifies, and MAY limit the total number of signatures they verify.
Verifiers MUST implement both 'simple' and 'relaxed' canonicalization algorithms. Verifiers MUST ignore any signatures that use unrecognized canonicalization algorithms.
Selectors subdivide the key namespace per signing domain, supporting multiple concurrent public keys. They are encoded as sub-domain labels and form part of the DNS query: selector._domainkey.domain.
The DKIM DNS TXT key record uses a tag=value format with tags: v= (version, RECOMMENDED, must be 'DKIM1'), h= (hash algorithms), k= (key type, default 'rsa'), n= (notes), p= (public key data, REQUIRED; empty value means revoked), s= (service type), t= (flags).
The DKIM-Signature header field stores the signature and all key-fetching data as a tag=value list. It SHOULD be treated as a trace header field, SHOULD NOT be reordered, and SHOULD be prepended to the message.
This document creates or updates nine IANA registries: Email Authentication Methods Registry, DKIM-Signature Tag Specifications, DKIM-Signature Query Method Registry, DKIM-Signature Canonicalization Registry, _domainkey DNS TXT Record Tag Specifications, DKIM Key Type Registry, DKIM Hash Algorithms Registry, DKIM Service Types Registry, and DKIM Selector Flags Registry.
Attacks involving extra header fields are possible because DKIM signs specific named header fields. An attacker may prepend additional header fields not covered by the signature. Signers SHOULD include all security-relevant header fields and MAY sign non-existent fields to prevent future insertion.
DKIM does not prevent replay or spam attacks: a valid signed message can be retransmitted to many recipients, since the signature does not bind the message to any specific recipient or envelope information.
DKIM relies on DNS for public key distribution and is therefore vulnerable to DNS attacks including cache poisoning. DNSSEC can mitigate these risks but is not required by the specification.
Revoking a key only prevents future verification; messages sent while a key was valid and cached by a Verifier may still appear valid. The gap between key compromise and effective revocation propagation is a fundamental limitation.
The l= (body length) tag can be misused: an attacker can append malicious content to a signed message and the signature will still verify for the covered prefix. Signers are discouraged from using l= and Verifiers should treat messages with l= and appended content with suspicion.
Signature verification ends in one of three states: SUCCESS (successful verification), PERMFAIL (permanent non-recoverable error such as signature verification failure), or TEMPFAIL (temporary recoverable error such as DNS query timeout). The SDID and result MUST be output for SUCCESS and TEMPFAIL.
DKIM-Quoted-Printable encodes characters as '=' followed by two uppercase hexadecimal digits. All control characters, 8-bit characters, DEL, SPACE, and semicolon MUST be encoded. FWS may be added at arbitrary locations and MUST be removed before decoding.
The DKIM-Signature header field tags: v= (version, plain-text, REQUIRED, value '1'), a= (algorithm, plain-text, REQUIRED, e.g. 'rsa-sha256'), b= (signature, base64, REQUIRED), bh= (body hash, base64, REQUIRED), c= (canonicalization, plain-text, OPTIONAL, default 'simple/simple'), d= (SDID, plain-text, REQUIRED), h= (signed headers, plain-text, REQUIRED), i= (AUID, dkim-quoted-printable, OPTIONAL), l= (body length, unsigned decimal, OPTIONAL), q= (query method, OPTIONAL, default 'dns/txt'), s= (selector, plain-text, REQUIRED), t= (timestamp, unsigned decimal, RECOMMENDED), x= (expiration, unsigned decimal, RECOMMENDED), z= (copied headers, OPTIONAL).