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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.