Domain verification using Let’s Encrypt DNS Challenge Type (dns-01)

11 Apr

Domain verification using Let’s Encrypt DNS Challenge Type (dns-01)

From the link, we will get a nice script to create SSL Certificates. The script has code to verify domain after uploading a file to a folder .well-known/acme-challenge in the document root. If the domain is not yet hosted , we have to verify the domain using DNS TXT record.

This post explains about domain verification using DNS method.

First of all download the script from the link
Then we can use most of it’s code for domain verification using DNS too.

We have to use response we get for

$response = $this->signedRequest(
                    "/acme/new-authz", array("resource" => "new-authz",
                "identifier" => array("type" => "dns", "value" => $domain)

This array will have challenge details for domain verification using http, dns etc.

To get dns challenge details, use the below code

$dns_challenge = array_reduce($response['challenges'], function ($v, $w) use (&$self) {
                return $v ? $v : ($w['type'] == "dns-01" ? $w : false);

From the dns challenge we can collect token and key authorization.

$dns_token = $dns_challenge['token'];

$dns_payload = $dns_token . '.' 
                    . Base64UrlSafeEncoder::encode(hash('sha256', json_encode($header), true));

You can see that token and key authorization are creating just like we create for http-01. Now the main difference is, how we calculate the DNS TXT Record.

For domain verification using http-01, we create a file named
and we put the payload as content of the file.

But for dns-01 domain verification, we are not adding TXT value as payload, but we calculate a string by below code.

// name of the domain
$name = '_acme-challenge'. $domain;

//points to
$dns_txt_record = Base64UrlSafeEncoder::encode(hash('sha256',$dns_payload, true));

Then we have to add $name and $dns_txt_record to the dns zone TXT record.
We can check weather the value is added correctly or not by typing below command in terminal.

dig txt _acme-challenge.[domain]

Then we can invoke the domain verification using dns-01 type.

$result = $this->signedRequest_dns(
                $challenge_uri, array(
            "resource" => "challenge",
            "type" => "dns-01",
            "keyAuthorization" => $dns_payload,
            "token" => $dns_token

If anybody need more explanation or help, please do post comments.
Will answer asap.


  1. I follow you so far – to the second code snippet – then get lost 🙁
    Can you supply the fully modified “Lescript.php” perhaps?
    A diff would also work.
    I really need stand-alone code rather than something that’s specific for WHMCS – as I wrote my own DNS/Web/Mail/EPP management system years before WHMCS and would prefer to avoid changing what I have.
    I will also need to pause for a while once the new TXT records are written – for DNS propagation – etc. Probably loop around looking on all Nameservers to check the new TXT records are available.
    Also need to tidy up and remove the TXT records once the Certificate is obtained.

    1. The second code snippet is to create dns challenge details.
      Then third snipper create the TXT record to be placed.
      I sent you a mail, please reply when you are online, so that i can help you.

    1. Made a lot of customization to the script. So I think the full code won’t help.
      Can you tell me where you face an issue while following the steps explained?
      Then can help to fix it.

Leave a Reply

Your email address will not be published. Required fields are marked *