Internet-Draft | PP Issuance | March 2022 |
Celi, et al. | Expires 8 September 2022 | [Page] |
This document specifies two variants of the the two-message issuance protocol for Privacy Pass tokens: one that produces tokens that are privately verifiable, and another that produces tokens that are publicly verifiable. The privately verifiable issuance protocol optionally supports public metadata during the issuance flow.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 8 September 2022.¶
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Privacy Pass protocol provides a privacy-preserving authorization mechanism. In essence, the protocol allows clients to provide cryptographic tokens that prove nothing other than that they have been created by a given server in the past [I-D.ietf-privacypass-architecture].¶
This document describes the issuance protocol for Privacy Pass. It specifies two variants: one that is privately verifiable based on the oblivious pseudorandom function from [OPRF], and one that is publicly verifiable based on the blind RSA signature scheme [BLINDRSA].¶
This document DOES NOT cover the architectural framework required for running and maintaining the Privacy Pass protocol in the Internet setting. In addition, it DOES NOT cover the choices that are necessary for ensuring that client privacy leaks do not occur. Both of these considerations are covered in [I-D.ietf-privacypass-architecture].¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The following terms are used throughout this document.¶
We assume that all protocol messages are encoded into raw byte format before being sent across the wire.¶
Issuers MUST provide one parameter for configuration:¶
The Issuer parameters can be obtained from an Issuer via a directory object, which is a JSON object whose field names and values are raw values and URLs for the parameters.¶
Field Name | Value |
---|---|
issuer-request-uri | Issuer Request URI resource URL as a JSON string |
As an example, the Issuer's JSON directory could look like:¶
{ "issuer-request-uri": "https://issuer.example.net/example-token-request" }¶
Issuer directory resources have the media type "application/json" and are located at the well-known location /.well-known/token-issuer-directory.¶
Clients receive challenges for tokens, as described in [AUTHSCHEME]. The basic token issuance protocols described in this document can be interactive or non-interactive, and per-origin or cross-origin.¶
The Privacy Pass issuance protocol is a two message protocol that takes as input a challenge from the redemption protocol and produces a token, as shown in the figure below.¶
Origin Client Issuer (pkI, info) (skI, pkI, info) +------------------------------------\ Challenge ----> TokenRequest -------------> | | (evaluate) | Token <----+ <--------------- TokenResponse | \------------------------------------/¶
Issuers provide a Private and Public Key, denoted skI and pkI, respectively, used to produce tokens as input to the protocol. See Section 5.4 for how this key pair is generated.¶
Clients provide the following as input to the issuance protocol:¶
key_id
computed as
described in Section 5.4.¶
challenge
, an opaque byte string. For example, this might
be provided by the redemption protocol in [HTTP-Authentication].¶
Both Client and Issuer also share a common public string called info
.¶
Given this configuration and these inputs, the two messages exchanged in this protocol are described below. This section uses notation described in [OPRF], Section 4, including SerializeElement and DeserializeElement, SerializeScalar and DeserializeScalar, and DeriveKeyPair.¶
The Client first creates a context as follows:¶
client_context = SetupPOPRFClient(0x0004, pkI)¶
Here, 0x0004 is the two-octet identifier corresponding to the OPRF(P-384, SHA-384) ciphersuite in [OPRF]. SetupPOPRFClient is defined in [OPRF], Section 3.2.¶
The Client then creates an issuance request message for a random value nonce
using the input challenge and Issuer key identifier as follows:¶
nonce = random(32) context = SHA256(challenge) token_input = concat(0x0001, nonce, context, key_id) blind, blinded_msg, tweaked_key = client_context.Blind(nonce, info)¶
The Blind function is defined in [OPRF], Section 3.3.3. If the Blind function fails, the Client aborts the protocol. Otherwise, the Client then creates a TokenRequest structured as follows:¶
struct { uint16_t token_type = 0x0001; uint8_t token_key_id; uint8_t blinded_request[Ne]; } TokenRequest;¶
The structure fields are defined as follows:¶
key_id
.¶
SerializeElement(blinded_msg)
. Ne is as defined in [OPRF], Section 4.¶
The value tweaked_key
is stored locally and used later as described in Section 5.3.
The Client then generates an HTTP POST request to send to the Issuer,
with the TokenRequest as the body. The media type for this request
is "message/token-request". An example request is shown below.¶
:method = POST :scheme = https :authority = issuer.example.net :path = /example-token-request accept = message/token-response cache-control = no-cache, no-store content-type = message/token-request content-length = <Length of TokenRequest> <Bytes containing the TokenRequest>¶
Upon receipt of the request, the Issuer validates the following conditions:¶
If any of these conditions is not met, the Issuer MUST return an HTTP 400 error to the Client, which will forward the error to the client.¶
If the Issuer is willing to produce a token token to the Client, the Issuer completes the issuance flow by computing a blinded response as follows:¶
server_context = SetupPOPRFServer(0x0004, skI, pkI) evaluate_msg, proof = server_context.Evaluate(skI, TokenRequest.blinded_message, info)¶
SetupPOPRFServer is in [OPRF], Section 3.2 and Evaluate is defined in [OPRF], Section 3.3.3. The Issuer then creates a TokenResponse structured as follows:¶
struct { uint8_t evaluate_response[Nk]; uint8_t evaluate_proof[Ns+Ns]; } TokenResponse;¶
The structure fields are defined as follows:¶
SerializeElement(evaluated_msg)
.¶
concat(SerializeScalar(proof[0]), SerializeScalar(proof[1]))
,
where Ns is as defined in [OPRF], Section 4.¶
The Issuer generates an HTTP response with status code 200 whose body consists of TokenResponse, with the content type set as "message/token-response".¶
:status = 200 content-type = message/token-response content-length = <Length of TokenResponse> <Bytes containing the TokenResponse>¶
Upon receipt, the Client handles the response and, if successful, deserializes
the body values TokenResponse.evaluate_response and TokenResponse.evaluate_proof.
If deserialization of any value fails, the Client aborts the protocol.
Otherwise, when deserialization yields evaluated_msg
and proof
, the Client
processes the response as follows:¶
authenticator = client_context.Finalize(context, blind, pkI, evaluated_msg, blinded_msg, info, tweaked_key)¶
The Finalize function is defined in [OPRF], Section 3.3.3. If this succeeds, the Client then constructs a Token as follows:¶
struct { uint16_t token_type = 0x0001 uint8_t nonce[32]; uint8_t context[32]; uint8_t key_id[32]; uint8_t authenticator[Nk]; } Token;¶
Otherwise, the Client aborts the protocol.¶
Issuers are configured with Private and Public Key pairs, each denoted skI and pkI, respectively, used to produce tokens. Each key pair MUST be generated as follows:¶
seed = random(Ns) (skI, pkI) = DeriveKeyPair(seed, "PrivacyPass")¶
The key identifier for this specific key pair, denoted key_id
, is computed
as follows:¶
key_id = SHA256(0x0001 || SerializeElement(pkI))¶
This section describes a variant of the issuance protocol in Section 5 for producing publicly verifiable tokens. It differs from the previous variant in two important ways:¶
Otherwise, this variant is nearly identical. In particular, Issuers provide a Private and Public Key, denoted skI and pkI, respectively, used to produce tokens as input to the protocol. See Section 6.4 for how this key pair is generated.¶
Clients provide the following as input to the issuance protocol:¶
key_id
computed as
described in Section 6.4.¶
challenge
, an opaque byte string. For example, this might
be provided by the redemption protocol in [HTTP-Authentication].¶
Given this configuration and these inputs, the two messages exchanged in this protocol are described below.¶
The Client first creates an issuance request message for a random value
nonce
using the input challenge and Issuer key identifier as follows:¶
nonce = random(32) context = SHA256(challenge) token_input = concat(0x0002, nonce, context, key_id) blinded_msg, blind_inv = rsabssa_blind(pkI, token_input)¶
The rsabssa_blind function is defined in [BLINDRSA], Section 5.1.1.. The Client then creates a TokenRequest structured as follows:¶
struct { uint16_t token_type = 0x0002 uint8_t token_key_id; uint8_t blinded_msg[Nk]; } TokenRequest;¶
The structure fields are defined as follows:¶
key_id
.¶
The Client then generates an HTTP POST request to send to the Issuer, with the TokenRequest as the body. The media type for this request is "message/token-request". An example request is shown below, where Nk = 512.¶
:method = POST :scheme = https :authority = issuer.example.net :path = /example-token-request accept = message/token-response cache-control = no-cache, no-store content-type = message/token-request content-length = <Length of TokenRequest> <Bytes containing the TokenRequest>¶
Upon receipt of the request, the Issuer validates the following conditions:¶
If any of these conditions is not met, the Issuer MUST return an HTTP 400 error to the Client, which will forward the error to the client.¶
If the Issuer is willing to produce a token token to the Client, the Issuer completes the issuance flow by computing a blinded response as follows:¶
blind_sig = rsabssa_blind_sign(skI, TokenRequest.blinded_rmsg)¶
This is encoded and transmitted to the client in the following TokenResponse structure:¶
struct { uint8_t blind_sig[Nk]; } TokenResponse;¶
The rsabssa_blind_sign function is defined in [BLINDRSA], Section 5.1.2.. The Issuer generates an HTTP response with status code 200 whose body consists of TokenResponse, with the content type set as "message/token-response".¶
:status = 200 content-type = message/token-response content-length = <Length of TokenResponse> <Bytes containing the TokenResponse>¶
Upon receipt, the Client handles the response and, if successful, processes the body as follows:¶
authenticator = rsabssa_finalize(pkI, nonce, blind_sig, blind_inv)¶
The rsabssa_finalize function is defined in [BLINDRSA], Section 5.1.3.. If this succeeds, the Client then constructs a Token as described in [HTTP-Authentication] as follows:¶
struct { uint16_t token_type = 0x0002 uint8_t nonce[32]; uint8_t context[32]; uint8_t key_id[32]; uint8_t authenticator[Nk]; } Token;¶
Otherwise, the Client aborts the protocol.¶
Issuers are configured with Private and Public Key pairs, each denoted skI and
pkI, respectively, used to produce tokens. Each key pair MUST be generated as
as a valid 4096-bit RSA private key according to [TODO]. The key identifier
for a keypair (skI, pkI), denoted key_id
, is computed as SHA256(encoded_key),
where encoded_key is a DER-encoded SubjectPublicKeyInfo object carrying pkI.¶
This document outlines how to instantiate the Issuance protocol based on the VOPRF defined in [OPRF] and blind RSA protocol defnied in [BLINDRSA]. All security considerations described in the VOPRF document also apply in the Privacy Pass use-case. Considerations related to broader privacy and security concerns in a multi-Client and multi-Issuer setting are deferred to the Architecture document [I-D.ietf-privacypass-architecture].¶
This document updates the "Token Type" Registry with the following values.¶
Value | Name | Publicly Verifiable | Public Metadata | Private Metadata | Nk | Reference |
---|---|---|---|---|---|---|
0x0001 | OPRF(P-384, SHA-384) | N | Y | N | 48 | Section 5 |
0x0002 | Blind RSA, 4096 | Y | N | N | 512 | Section 6 |
This specification defines the following protocol messages, along with their corresponding media types:¶
The definition for each media type is in the following subsections.¶
message¶
token-request¶
N/A¶
None¶
only "8bit" or "binary" is permitted¶
N/A¶
this specification¶
N/A¶
N/A¶
see Authors' Addresses section¶
COMMON¶
N/A¶
see Authors' Addresses section¶
IESG¶
message¶
access-token-response¶
N/A¶
None¶
only "8bit" or "binary" is permitted¶
N/A¶
this specification¶
N/A¶
N/A¶
see Authors' Addresses section¶
COMMON¶
N/A¶
see Authors' Addresses section¶
IESG¶
The authors of this document would like to acknowledge the helpful feedback and discussions from Benjamin Schwartz, Joseph Salowey, Sofia Celi, and Tara Whalen.¶
This section includes test vectors for the two basic issuance protocols specified in this document. Appendix B.1 contains test vectors for token issuance protocol 1 (0x0001), and Appendix B.2 contains test vectors for token issuance protocol 2 (0x0002).¶
The test vector below lists the following values:¶
The info
parameter used when computing the token is the ASCII string "Privacy Pass".¶
skS: accb1467936ba0c06500acc592633dd19c7d8cd752fc3975f6fd3123b993a703a84 f0a7d88949bd41ec9c655459c9b47 pkS: 03fa7bb43a5223538e3bfd06e817af754d6a950a86eb88a134dacbb3f5c4cff47e4 a8a8f4cea5eb2cf162a913a985167f8 challenge: f7e31518291770916d2164b7ec4a7a32698588fdaef0428812069b54dbc70bca nonce: ae576e03963659fe07badeccb21967ad5d893e09a1ad71635367d87fb932ca39 blind: 4a13636159a6769241dcb439d7e2ff604ce971d217edb20f1f8ad7b28faf841e5 1688a95e722554d2ea796f40c010c4c token_request: 000178036e06b416f09c58bd9ca0a6c5d60391e0d993fc2ffdea33963 f3c7d6c421a8c36d9b1d2f1164fd94a4be70651d1745e01 token_response: 036544d94b1e2b3518bcbf6a80e85779f516406c5b41d1c2d35e6f22 dc7d61708736f0768a3bc7313f42e06be5674db27cc2af138521a9dc979ea2ca4636bec9 0d21258aba98e4f322ec4a443bf8976fe5529dd92dd60c2e6f3c9030fcdb2621bf0e25c5 0d9deb319df250a9ec40ec121e1852f2365007ca0b330cb9edbff46daa89087fc3d8cf2f d33979c2a6d8f64fed token: 0001ae576e03963659fe07badeccb21967ad5d893e09a1ad71635367d87fb932c a39ebecc2a0a1a2beef6f8457a256501ff3d943f9a18a507f21069bd960542420b178d37 692bdb29cedf2e6c44adc55d7b8909584e5a9096005aeb5b8913a69c681e7a5d48fd687f fb181512ba16d6472489b363ad84047b4e1701d50f30fa03516eae4ca715698f37c68d16 0c7ffb0dbd4¶
The test vector below lists the following values:¶
skS: 2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0a4d49494a517 749424144414e42676b71686b69473977304241514546414153434353307767676b70416 74541416f4943415144584d4d364c5073637a6130696b0a39596c315a4e683868324a796 d504962704c383035354d52516f6463446c4c4672764d694c57666f59535241506b4e744 1546272324162654e334d454a2f67550a392f424958717a704d4256484852546c627a676 b364c7866766b54505a2b4a427832517177364f5555714b442f34426f5464765761536d6 a63644165555037760a4836376e396a383836307463367375546e67616c574d4b6d764d2 f5a6237644262543763345647386577706c6776444f6d616641353956354f78505545704 9510a586c454f4771414f43436c316f54686d33363836436c48413352374c5a4d78567a4 742386f594537583548396a70793532786a2f3242724a6861625033567a430a6f4c696c3 54f6e36487158785363466d4956573742787956495979756d75537659544e52757652777 3566c3775595446366f4d6d2b59722f5a506372594c7a510a4e666135634f747533532b6 649594456716f6f58375541415671382f716c4945747a794a744f7261616756393039327 0324f474c4f6d306a52384543666963520a3868363332572f76554d7739724c4c317a4d4 e7554424f4b74316c546c307265644a677668626b66515a5a55303541336a69366c71754 d2f47307250553030470a3369385253732f64694e625843505453746b616f45537350345 946496d526269756c786a544e2b626c5859744868494261556774306e2b566b544a77554 86e380a5367447534664e547142776567517265494e427732446b6e63576e676b5644416 867577635383669727351644c345843723376765856647a51375134586978730a465a6b6 d7763676d665142444f3469363078536c336337316954595362783359326e74584b4e6f5 a4c31537a424f595051496a6c734749454250677157546e5a0a64655a7852464f6c4d384 679794b6d30746471586271594b57716b663777494441514142416f4943414364314d707 044773645424467763558654168777252710a32726c717042492f6a6a50304e6e7057755 a302b6e787a53624a4361784d2f4f61436844676e654e586e573259655144524e7242505 84d5331344e646f4e554e0a56516c36497166445567637169636741696e7542622f4a687 a6c4d74466d5350466d2b667650726a4d2b6c4831544f384863354253633274414a52574 36468770a794a7663446349656d74646378437877754b6746485251704a5071356368526 56431535077766f50494c7831686959356c2f5175423478717a764149483873530a34673 949705a2f766169443558573541335847734a4f2b696a78717250706756655236474e4f5 33763515551716a44446967665a626a5864354a322b734d79460a4c435a6e514d6771577 03731756437366a4f4a445571563537454154534e6b56472f52633279537a554b4d6e354 c335a314a796d6d31694f584a5136535744760a6f5375426b435652436645635a746b546 f436c76646f5456666b63414a394e51343839686b3050754e466f593675315671614c5a4 a7764657a3931764f5966300a4b676f665a4a6e774976547733754b786f7559685033334 43644574a4f31763265487658767a4c744f4a54477054446f726f4c7a2f475459316b682 f484d50510a416c4f333758772f526b527752684b4d6f39545555347766642b2b5348325 4346e6730584875355254764d5339496b4266724455337a75557675434b7270356b0a377 942364473763433517932364f6367367151584a563650676b6c5770696164445778326f4 73935746578436f3346563434764a6d49327a706d5748514257630a48395331336b6d7a3 06873506274576a537535494c443061694f5630764d4c61353841685a767a32774562763 750546a494d48364d77446736326d6450744d6b0a534969517548644a38326a69316e757 8646f5678416f4942415144773431456757476e437644496239727a73704b6e61486a654 3574650385737664a6b446c4c0a61786c724a6f574e614d654c33306b646873576569765 7616730436f457656556631543455374936735a33705054675653685079374b6f4c645a4 86f757a5a390a4d774679716d694652726e574135467138544b756f4354647a3836542f5 37859753330625a476c6d6a4c432f6664453279556141486f6f5177375a2f34646b6d0a4 1693031696a36484d654e39486e5a425737656c436c4173443242436d4b5279655554793 7754b472b6b3732704630336e45694f7a42615565354d6c7a7436620a3867586b63715a5 735495478454b41726b6d486a77454379765178346a7867324573326a7653654e3041554 b624a63534a736e7a35434a65667a697561676f650a36482b3947676f62386e496a78546 34e784c7a58316a676e5236772f41302f6e657837714e6b57357773485a46644c58416f4 9424151446b734d6e75503452460a7558474a6e34316559696c43716b694e4e6b4a53753 9637456556b7772364570744230506d34556e3770535238684866767a5a43782f6b65766 b33553336546e0a67556c72416a4b72474a6a77437231457a7252726e417153466f61395 04851395a69697264626336726f474932576f63795a585859664b784a56646a4f754c440 a793947564d72575133665a3571696d7a6a394b4163304852455765784b6875514259465 554542f44323169584b4b65497568647834796b795435323857714b310a66786f4c72584 e6d5936726b77787778763334556779685a54564a75454879506e51422f54743242377a2 b342f763033665a46347361635646337738514a306c0a692b466879555a34326b63674a3 52b654c6d5558726b6d5a5959314a534332417a722f336449516a4b554655515935326a3 65775667338392f576a72516669470a31732b6c51385a7a6d4a4370416f49424151432b3 84c43686e764e574e4b37546b365431507943546b466758726351457950374a657453766 6316c4b6f654a430a304d6337692b58387a5a4e6674473478353941636163716c43376c6 96a5a55394351564f6d415159652f754d4679524371524c62453271426d79694f70357a7 00a3538487562693261513034564e554f44767644555256346468364148556e52706f534 f49356b59723079646137746f7070376a4662565165324b4c56535a742b0a746f4448384 a6c7a2f5374345774427033465a4538354747573748586a70746f756f6855344c777a464 7492f4c6d37486935783733357038716a385a6366642f0a384f756632626e6354382f674 938676b35633034307451794b483177534d4e4e6d5a496c54535943635653725369346b4 5567677684955354d726e75507647380a6256556b48584d694b7377316d63777739704d4 6373634716f6d464337586f66594d30664d6a6c4a416f494241465079565632676354534 b2b784e7976786b4c0a58577638522f2b57454569416256395674445572387a503079736 f6b34333869412b57432f32367271515a676b36446d61486d673073367356622f7a495a6 84f0a7769307a4e41446a41375751705179314f6961533333522b594b56333435656c345 35454386a433543736a79536e306559504b71396679376636614e343770570a304267664 4346d37584b454d4c66664a744d2b437a6e56536f41504c433449677257646e5a4141376 c306d57416c52576832645275664a3377703751763943770a2b315659446178785235334 e2b327930686e4b696d4b613745696970555952567834566f444a6c6d2f5a525a5769545 335796253375279514f563645334e71560a2f592f6647366563446a33674732497a50674 c4e664f3651646b556d7679364e4155386c645638754962707045446749497042684f684 a394865486a664343490a75326b4367674542414d68686e6f69312b78454a365339636e5 a327977527737433057544962662b54557230436e374f344a4d76637843544b484d62773 76a680a574c6247392f314732595966354c5673326b572f34472b2f446d586b6d4b68715 4746d6f324e50463666504b73694d64477877354149677039557a50543168550a2f6c777 26a75474d322f2b77434b70316d3645374e4d4d5659684b5841534f673473652b3676586 455356a56436f634343576162657a6c5835513262796c51480a2b2b624f6d4661504d535 5683761616d6657357573614553627366612f45506932446d3545574f456339567577525 671526143527552534632507043627279410a6b376e6b6b6746474b5a523777353053465 5366f7a776667627a2b7a33637256315535766d3076346c63794b6d524b6c4b575a51554 9624b782f5070583737640a395057536e3569594343704c432f316245372f566f4c70467 7757631656a773d0a2d2d2d2d2d454e442050524956415445204b45592d2d2d2d2d0a pkS: 30820252303d06092a864886f70d01010a3030a00d300b060960864801650304020 2a11a301806092a864886f70d010108300b0609608648016503040202a20302013003820 20f003082020a0282020100d730ce8b3ec7336b48a4f5897564d87c87627298f21ba4bf3 4e7931142875c0e52c5aef3222d67e86124403e436d0136ebd806de37730427f814f7f04 85eace93015471d14e56f3824e8bc5fbe44cf67e241c7642ac3a39452a283ff80684ddbd 66929a371d01e50feef1faee7f63f3ceb4b5ceacb939e06a558c2a6bccfd96fb7416d3ed ce151bc7b0a6582f0ce99a7c0e7d5793b13d41292105e510e1aa00e082975a13866dfaf3 a0a51c0dd1ecb64cc55cc607ca1813b5f91fd8e9cb9db18ffd81ac985a6cfdd5cc2a0b8a 5e4e9fa1ea5f149c1662155bb071c95218cae9ae4af613351baf470b1597bb984c5ea832 6f98aff64f72b60bcd035f6b970eb6edd2f9f2180d5aa8a17ed400056af3faa5204b73c8 9b4eada6a057dd3dda9d8e18b3a6d2347c1027e2711f21eb7d96fef50cc3dacb2f5ccc36 e4c138ab75953974ade74982f85b91f419654d390378e2ea5aae33f1b4acf534d06de2f1 14acfdd88d6d708f4d2b646a8112b0fe181489916e2ba5c634cdf9b95762d1e120169482 dd27f959132705079fc4a00eee1f353a81c1e810ade20d070d839277169e09150c08605a fe7cea2aec41d2f85c2af7bef5d577343b4385e2c6c159926c1c8267d00433b88bad314a 5ddcef58936126f1dd8da7b5728da192f54b304e60f4088e5b0620404f82a5939d975e67 14453a533c172c8a9b4b5da976ea60a5aa91fef0203010001 challenge: 83ce743dcdadd5fc4aeb0357977bb8426635c390a15b88947f0b1c62e4a87c22 nonce: 7e0da97bfdc4365a5f40e69262f78b81bcd2f92daf885358d9831874e3dd9d22 blind: cd6d03e332386d0166eb76b8e78522510e5cbdcf49aaac83191ea948a7719e914 0ccb6701f7301b7d445ede7adbc5e582b35edd9ac45bc4b8f794e150b2e3e407b7b7624b 6f90b33845bc255174cee0c570aa781c203dce8563afe9f48e2b49c773bba1031987fb48 d981d131876f53e264ec0609a3ea628cf2042005ed3071aeb6657472c7e7df947915b8cd 333e3f5078e456e65e5edef8f892c4f21d25a18dcd80628ed6c7d55b0b9433bc67760be0 8a4eacbdb16a4be4c5b8cab26b478fa6a36ea3c3dd1ffb420bf69feef52aab4892c9e60a df18347b4e8256b5a0e8cbf55fc97ac62af2e7349ba98ca7462cb6a41d70b0217814a06e 1b257289c3b345be652b87d5820b06a80500880b40b8772140bf431f11497114b20fee7e 5ffc1af5cf874cc293a0c8df65d52814bcd55ae6d3701f73d140ca82c6528627129ea389 f3cbd6058f4f80b7df3818f36dd3489259b6b95df4511930ff02b5cbe643fea44306e7c4 e3d9b02f1b0559aa238b8882a6e8791bfbfd366ef4fe433fd42e5c5db208c9fcebc74def 11663ce5f793c7013116995b3fef392a8633b08179a9c8309fb69359fd8486a7a8febb42 4d0726c2516b11e8b19a55fa54e9be606de6811059976473de8f9adb25af7e2862932bed c7764b4dc50bfc9d724a4aba356a7677b5aceef21876e56b4f1b65adef0fbf8bf1636815 be01b372727e79aa6c47f41 salt: d13a47fa6466a37203e51ac34f7319831b3f04202ff74c98ab18e78088b7ac3014 06189783503227153871405c6a1da0 token_request: 0002013a370077e8259098e741dcaac8184838b7c995cd82966419064 90205bf28e6745396dd9ec1761c4676e9fec3272588194c48bc60fc77c3fff19219a6b65 96523044d07d9d9e4dd88f2db9d9c369597363a12a65d244d69a1b743b365f8f5bdbf8d6 52f2d2e249f417e9fd7da7db2626d6499d7d3856d8f9277385dfd776ffa4ffa74d7a7b17 01d87f40e525bb258a7f5b4d6c134b3b242ef46d93b32f106c84c396b1fc2772796b2473 64c48c364537708f3a8a87fb870a299ac08107a5dd3f467733d76c2359e346ee3ebcff68 c3c7e10f0f01a2b9bbbdb26ffea14f81f036a71c47725b5c9f81e0320b85abfd77d5eb1c ccfdd8eb0cf2735ea297e2a07c82dfee9b0a4d21baa81a2cfb2a72983107555035386c33 973d48f04257dd8298116d2c93298810cb6b82ad033f5b16f9f7a65d8f74b7bdcae000db 1411b40f46cb373cb69c8ab58552f98904b78229b63838ab40e833fab4ec47acf00a00db 3290c9c74ed982c64ddbcae16fd73976ffe7da7b3b1a8e0190e95b7ce7900295f3c8c94f 2d3d85cd1825fe27073aad63fa4c530907402dc4e3a748edb300f05ce7ac5b8c1d9aeb2f d6002b05dee582aeaefa4f503f13bae1a51be9420e3cdcb685169bdc5ae2ebca7713ec16 666b55b097e56e5719d1b0324ecaca613af76b9f367775a90dba5e7fdd21a8da73bd80b1 31e6531117ef709ad8c7b2b3182255235acea token_response: 061780e09bc9b851fe81e7022ee2d55b043198bcb1aa33f761d213a9 8d831abaef5417d30904a7c9d7ec531278cd9655c4b7d72f3a4e66e26565b73e5f1b9271 b541f28556543d2473c363e104a11c6ba1a1d8f99b32d3cd8f74ae07b465afdaabd21977 d6f114ea9484cd592f461e5dc4a97b86fe1463b1c69171cf734f49c240760dc2555d7cc8 9d7f882d3e1b99388bc3b561d418a7fc5770ccc66e3dd41f4a74e8267492f48e8b6aabce 592c8dc83826b1f4528f2497902a0ce4baacd4216623274057592e77091102452de115bb d0c98ee22b14fe30fb371277ab17bc948b62b8adb56b67e44dce74860647718c8f4bd10e 7b022ad35e2996dd49fb4a6c765689931fc11b56b06cca921fb1205e8b230254054a48da 38ed7a5e20f7aa80b55f1de9f5a6c9589f4f2c3b6ed2c53ad2a6a64abb8fba67aef86e6f f77647aa05ce96527e2d1199b7553a3b900ec510f5b765211c14d0fc6cbe82f28be4d8ac 8110f13d7aee3741fc68f4abf3ca33444f790a72ef4ddec72c1d92938ee5d303f914ff12 8d9a73e867d9aa5d327934d4b2b299d7ffa32350d72d35103c027ac76c5417823e6790ee 174b9761e086bfa445f1725b20cff6a94d51abdfcfe46ff7c0f69685fd38639bdbd3917f 424949027b5a322fc217364748e544257d11f0cdcab9aa1d3282f6ac2811dfc8db5b2f99 c1ba00c366057748cabe6975fc73ed60 token: 00027e0da97bfdc4365a5f40e69262f78b81bcd2f92daf885358d9831874e3dd9 d22895c9d3ff72e71d22cdbc11706d350ab772b0820be9f33a02e003652cb00a31501000 000000000000000000000000000000000000000000000000000000000004c9e19f2a624e e7d44ac35846749b29b1d3a784f13ea1005a2c87b9d3f939f795877d5fded823f45fd399 dc0b8730cb46c66102740c679338b7093c47e8f586e48a8b042cb0ea2b901f6981e797c4 a614f52f02ffe3ae7f83fa4f9a243e8b59621975abffb94f82b3fadfb4cb305cc1c1b677 42a673204e5a0aa0c25423c604430597d0332e30dddab8855de42bcf49668410df38bb3b fa4370df28ec59316bc1c6f3c9afc8ccfdb93f4ca60365683988f649201e1c6d6bb73d14 d0dc9a0f596a9f76502ebadc0b248985f9bb66d9d99a5aca08527aa11d555b26489299ba 5b400157a9fd47b6b4fa74315eade2b22624b29d53eb84126f64b98ea5ba45914d1fa14b 1525e2327856565054a1db9b0d778871fa6ed4d0d4c26641bf3f4faa33efaa0f5b8cec80 8d52ed3f1378273d5b7b0b0b812bfc128ef5e4924a60aebd124659d31661e9ec89f8bcb9 a51bab6a5711187639c24fdd31f14abf7d80827df91f31bfe7c4916ec4d1927ca138c5ba 9a595a9e83b5055148d19ad005c523eda76ea94006ce6315e20ed0d637fb1211b541e9ea 12c9b641d48fd2cc5f0c7f479672a4e2bf7469267c8526d734df41f2c30fb62c2aea4033 214df44a53353dc683cf72dee7b1ba39ef668478958935a0e8c9a880ae85712c401d7f09 b66fbad05cfd69d615b229bce8818c6a6472e07a8793456f19f4f4015c507ab5c1357881 68b¶