DNS Security: DNSSEC, KSK/ZSK, and the Chain of Trust
Why DNSSEC? #
Plain DNS has no integrity check — a resolver has no way to tell a legitimate answer from a forged one. DNSSEC adds digital signatures to DNS records so a resolver can cryptographically verify that a response came from the zone’s real holder and wasn’t tampered with in transit.
It relies on three new record types:
- DNSKEY — the zone’s public key(s)
- RRSIG — a signature over a set of records (an RRset), created with the zone’s private key
- DS (Delegation Signer) — a hash of a child zone’s KSK, published in the parent zone
The two-key model: KSK and ZSK #
DNSSEC separates duties between two key pairs, distinguished by the DNSKEY record’s flag field (RFC 4034):
| Key | Flag | Role |
|---|---|---|
| ZSK (Zone Signing Key) | 256 | Signs the zone’s regular records (A, MX, CNAME, etc.) |
| KSK (Key Signing Key) | 257 | Signs the DNSKEY RRset itself (i.e., signs the keys, not the data) |
Both public keys are published together inside the same DNSKEY RRset.
Verification flow #
- The resolver fetches the DNSKEY RRset, the A RRset, RRSIG(DNSKEY), and RRSIG(A).
- It verifies RRSIG(DNSKEY) using the KSK public key — confirming the DNSKEY set (including the ZSK) is internally consistent.
- Once the ZSK is trusted, it verifies RRSIG(A) using the ZSK public key — confirming the A records are authentic.
For RSA signatures, verification recovers a hash from the signature using the public key and compares it to a locally computed hash. For ECDSA (which AWS uses), verification is a combined pass/fail operation rather than one that hands back a recoverable hash — but the underlying intent is the same: prove the data matches what the private key actually signed.
Breaking the circularity: the DS record #
Step 2 above has a gap: the KSK public key used to verify RRSIG(DNSKEY) comes from the very DNSKEY set being validated. An attacker could supply a fake DNSKEY set with a matching fake KSK and fake RRSIG(DNSKEY), and the check would still pass.
What breaks this circularity is the DS record in the parent zone:
- The parent zone (e.g.
.com) holds a DS record for the child zone (e.g.example.com) that is a hash of the legitimate KSK public key. - That DS record is itself signed by the parent’s own keys.
- The resolver hashes the KSK from the DNSKEY set and compares it against the DS record obtained from the parent. A match means the parent vouches for this KSK.
- The parent’s own keys are, in turn, vouched for by its parent, all the way up to the root trust anchor, which the resolver trusts inherently.
Complete validation flow:
- Get the DNSKEY set, RRSIG(DNSKEY), A set, and RRSIG(A).
- Validate the KSK against the parent’s DS record (hash the KSK, compare to the DS record) — confirms the KSK is genuine, breaking the circular trust problem.
- Verify RRSIG(DNSKEY) with the now-trusted KSK — confirms the DNSKEY set, including the ZSK, is authentic.
- Verify RRSIG(A) with the now-trusted ZSK — confirms the A records are authentic.
- The DS record itself is trusted because it’s signed by the parent, chaining up to the root.
AWS Route 53 implementation #
- Route 53 DNSSEC signing uses ECDSAP256SHA256 (algorithm 13, based on the ECC_NIST_P256 curve) for both the KSK and ZSK.
- The KSK is backed by an asymmetric customer managed key in AWS KMS. That KMS key must be created in
us-east-1, because Route 53 is a global service whose control plane runs inus-east-1— KMS keys are regional, so they must live in the same region as the control plane that uses them. - The ZSK is managed and rotated automatically by Route 53 itself.
Sources: