Consider the following dig command and its truncated output:

dig . dnskey +dnssec +multi @a.root-servers.net
.                       172800 IN DNSKEY 257 3 8 (
                                ) ; KSK; alg = RSASHA256 ; key id = 20326

The ICANN website lists multiple different hashes in the root-anchors.xml file and the two PDFs with physical signatures.

I attempted to run sha256sum directly on base64-decoding of the above DNSKEY record and got d6b602bc8f107abe8e9b68c2d0afbfe1ca655767063b1d20c31a6398f3521d2e, which does not match any of the hashes as far as I can tell.

What set of commands can I run on output of the dig command to get or verify any or all of the hashes listed on the ICANN website?


1 Answer 1


RFC 4034 specifies in section 5.1.4 how the digest field in DS records is computed:

   The digest is calculated by concatenating the canonical form of the
   fully qualified owner name of the DNSKEY RR with the DNSKEY RDATA,
   and then applying the digest algorithm.

     digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);

      "|" denotes concatenation

     DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.

The wire format of DNSKEY records is specified in section 2.1 of the same RFC:

   The RDATA for a DNSKEY RR consists of a 2 octet Flags Field, a 1
   octet Protocol Field, a 1 octet Algorithm Field, and the Public Key

The encoding of domain names is specified in section 3.1 of RFC 1035:

Domain names in messages are expressed in terms of a sequence of labels.
Each label is represented as a one octet length field followed by that
number of octets.  Since every domain name ends with the null label of
the root, a domain name is terminated by a length byte of zero. […]

Putting all of this together, we have to concatenate the following data:

root-anchors.xml lists 2 as the digest type for the key with the id/tag 20326:

<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">

According to this list, this means that we have to hash the above data with SHA-256.

When we paste the following into a shell, we get the desired result:

$ { echo -en '\x00'; echo -en '\x01\x01'; echo -en '\x03'; echo -en '\x08'; echo 'AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=' | openssl base64 -d; } | openssl sha256

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .