Original text:
7.1. <del> Several of the challenges in this document makes use of an "authorized key" object.  Such an object is a JSON object that encodes an authorization for a specific account key to fulfill a specific challenge. A random value that uniquely identifies a challenge.  This value MUST have at least 128 bits of entropy, in order to prevent an attacker from guessing it.  It MUST NOT contain any characters outside the URL-safe Base64 alphabet. The account key being authorized </del>  7.2. The string "http-01" <del> A serialized authorized key object, base64-encoded.  The "key" field in this object MUST match the client's account key. </del>  <del> A client responds to this challenge by base64-decoding and parsing the authorized key object, verifying that its "key" field contains the client's account key, and provisioning it as a resource on the HTTP server for the domain in question.  That is, the server provisions a JSON object that is equivalent to the object encoded in the "authorizedKey" field sent by the server.  (Note: The provisioned object need not be a byte-exact copy of the authorized keys object in the challenge.) </del>  The path at which the resource is provisioned is comprised of the fixed prefix ".well-known/acme-challenge/", followed by the "token" value in the challenge. The client's response to this challenge indicates its agreement to <del> this challenge: </del>  <del> The string "http-01" </del>  <del> The "token" value from the authorized key object in the challenge. On receiving a response, the server MUST verify that the "token" value in the response matches the "token" field in the authorized key object in the challenge.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge </del>  Given a Challenge/Response pair, the server verifies the client's control of the domain by verifying that the resource was provisioned Form a URI by populating the URI template RFC6570 "http://{domain}/.well-known/acme-challenge/{token}", where: * the domain field is set to the domain name being verified; and * the <del> token field is set to the token in the authorized key object. </del>  Verify that the resulting URI is well-formed. HTTPS server. Verify that the Content-Type header of the response is either <del> absent, or has the value "application/json". Verify that the body of the response is well-formed authorized key object. </del>  <del> Verify that the "key" and "token" fields in the authorized key object match the values from the authorized key object in the challenge. </del>  <del> Comparisons of the "token" field MUST be performed in terms of Unicode code points, taking into account the encodings of the stored nonce and the body of the request. </del>  If all of the above verifications succeed, then the validation is successful.  If the request fails, or the body does not pass these The string "tls-sni-01" <del> A serialized authorized key object, base64-encoded.  The "key" field in this object MUST match the client's account key. </del>  Number of tls-sni-01 iterations <del> In response to the challenge, the client MUST decode and parse the authorized keys object and verify that it contains exactly one entry, whose "token" and "key" attributes match the token for this challenge and the client's account key.  The client then computes the SHA-256 digest Z0 of the JSON-encoded authorized key object (without base64-encoding), and encodes Z0 in UTF-8 lower-case hexadecimal form.  The client then generates iterated hash values Z1...Z(n-1) as follows: </del>  The client generates a self-signed certificate for each iteration of Zi with a single subjectAlternativeName extension dNSName that is The response to the TLS SNI challenge simply acknowledges that the client is ready to fulfill this challenge. <del> The string "tls-sni-01" The "token" value from the authorized key object in the challenge. </del>  <del> On receiving a response, the server MUST verify that the "token" value in the response matches the "token" field in the authorized key object in the challenge.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge </del>  Given a Challenge/Response pair, the ACME server verifies the client's control of the domain by verifying that the TLS server was Choose a subset of the N iterations to check, according to local policy. <del> For each iteration, compute the Zi-value from the authorized keys object in the same way as the client. </del>  Open a TLS connection to the domain name being validated on the requested port, presenting the value The string "dns-01" <del> A serialized authorized key object, base64-encoded.  The "key" field in this object MUST match the client's account key. </del>  <del> In response to the challenge, the client MUST parse the authorized key object and verify that its "key" field contains the client's account key.  The client then computes the SHA-256 digest of the JSON-encoded authorized key object (without base64-encoding). </del>  The record provisioned to the DNS is the base64 encoding of this digest.  The client constructs the validation domain name by The response to the DNS challenge simply acknowledges that the client is ready to fulfill this challenge. <del> The string "dns-01" The "token" value from the authorized key object in the challenge. </del>  <del> On receiving a response, the server MUST verify that the "token" value in the response matches the "token" field in the authorized key object in the challenge.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge </del>  To validate a DNS challenge, the server performs the following steps: <del> Compute the SHA-256 digest of the authorized key object </del>  Query for TXT records under the validation domain name

Reviewer comments:
This PR updates the new challenges so that they no longer use a JSON object dictated by the server. Instead, they use a "key authorization" string that is canonically generated from the token and key for a given challenge. (And also, while we're here, changes "authorized key object" to "key authorization".)

Revised text:
7.1.  <ins> Several of the challenges in this document makes use of a key authorization string.  A key authorization expresses a domain holder's authorization for a specified key to satisfy a specified challenge, by concatenating the token for the challenge with a key fingerprint, separated by a "." character: The "JWK_Thumbprint" step indicates the computation specified in RFC7638, using the SHA-256 digest.  As specified in the individual challenges below, the token for a challenge is a JSON string comprised entirely of characters in the base64 alphabet.  The "||" operator indicates concatenation of strings. In computations involving key authorizations, such as the digest computations required for the DNS and TLS SNI challenges, the key authorization string MUST be represented in UTF-8 form (or, equivalently, ASCII). </ins> 7.2. The string "http-01"  <ins> A random value that uniquely identifies the challenge.  This value MUST have at least 128 bits of entropy, in order to prevent an attacker from guessing it.  It MUST NOT contain any characters outside the URL-safe Base64 alphabet. </ins>  <ins> A client responds to this challenge by constructing a key authorization from the "token" value provided in the challenge and the client's account key.  The client then provisions the key authorization as a resource on the HTTP server for the domain in question. </ins> The path at which the resource is provisioned is comprised of the fixed prefix ".well-known/acme-challenge/", followed by the "token" value in the challenge. The client's response to this challenge indicates its agreement to  <ins> this challenge by sending the server the key authorization covering the challenge's token and the client's account key: </ins>  <ins> The key authorization for this challenge.  This value MUST match the token from the challenge and the client's account key. </ins>  <ins> On receiving a response, the server MUST verify that the key authorization in the response matches the "token" value in the challenge and the client's account key.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge. </ins> Given a Challenge/Response pair, the server verifies the client's control of the domain by verifying that the resource was provisioned Form a URI by populating the URI template RFC6570 "http://{domain}/.well-known/acme-challenge/{token}", where: * the domain field is set to the domain name being verified; and * the  <ins> token field is set to the token in the challenge. </ins> Verify that the resulting URI is well-formed. HTTPS server. Verify that the Content-Type header of the response is either  <ins> absent, or has the value "text/plain". </ins>  <ins> Verify that the body of the response is well-formed key authorization. </ins>  <ins> Verify that key authorization provided by the server matches the token for this challenge and the client's account key. </ins> If all of the above verifications succeed, then the validation is successful.  If the request fails, or the body does not pass these The string "tls-sni-01"  <ins> A random value that uniquely identifies the challenge.  This value MUST have at least 128 bits of entropy, in order to prevent an attacker from guessing it.  It MUST NOT contain any characters outside the URL-safe Base64 alphabet. </ins> Number of tls-sni-01 iterations  <ins> A client responds to this challenge by constructing a key authorization from the "token" value provided in the challenge and the client's account key.  The client first computes the SHA-256 digest Z0 of the UTF8-encoded key authorization, and encodes Z0 in UTF-8 lower-case hexadecimal form.  The client then generates iterated hash values Z1...Z(n-1) as follows: </ins> The client generates a self-signed certificate for each iteration of Zi with a single subjectAlternativeName extension dNSName that is The response to the TLS SNI challenge simply acknowledges that the client is ready to fulfill this challenge.  <ins> The key authorization for this challenge.  This value MUST match the token from the challenge and the client's account key. </ins>  <ins> On receiving a response, the server MUST verify that the key authorization in the response matches the "token" value in the challenge and the client's account key.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge. </ins> Given a Challenge/Response pair, the ACME server verifies the client's control of the domain by verifying that the TLS server was Choose a subset of the N iterations to check, according to local policy.  <ins> For each iteration, compute the Zi-value from the key authorization in the same way as the client. </ins> Open a TLS connection to the domain name being validated on the requested port, presenting the value The string "dns-01"  <ins> A random value that uniquely identifies the challenge.  This value MUST have at least 128 bits of entropy, in order to prevent an attacker from guessing it.  It MUST NOT contain any characters outside the URL-safe Base64 alphabet. </ins>  <ins> A client responds to this challenge by constructing a key authorization from the "token" value provided in the challenge and the client's account key.  The client then computes the SHA-256 digest of the key authorization. </ins> The record provisioned to the DNS is the base64 encoding of this digest.  The client constructs the validation domain name by The response to the DNS challenge simply acknowledges that the client is ready to fulfill this challenge.  <ins> The key authorization for this challenge.  This value MUST match the token from the challenge and the client's account key. </ins>  <ins> On receiving a response, the server MUST verify that the key authorization in the response matches the "token" value in the challenge and the client's account key.  If they do not match, then the server MUST return an HTTP error in response to the POST request in which the client sent the challenge. </ins> To validate a DNS challenge, the server performs the following steps:  <ins> Compute the SHA-256 digest of the key authorization </ins> Query for TXT records under the validation domain name