Internet-Draft | json-web-proof | July 2022 |
Miller, et al. | Expires 25 January 2023 | [Page] |
The JOSE set of standards established JSON-based container formats for Keys, Signatures, and Encryption. They also established IANA registries to enable the algorithms and representations used for them to be extended. Since those were created, newer cryptographic algorithms that support selective disclosure and unlinkability have matured and started seeing early market adoption.¶
This document defines a new container format similar in purpose and design to JSON Web Signature (JWS) called a JSON Web Proof (JWP). Unlike JWS, which integrity-protects only a single payload, JWP can integrity-protect multiple payloads in one message. It also specifies a new presentation form that supports selective disclosure of individual payloads, enables additional proof computation, and adds a protected header to prevent replay and support binding mechanisms.¶
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 25 January 2023.¶
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 JOSE specifications are very widely deployed and well supported, enabling use of cryptographic primitives with a JSON representation. JWTs [RFC7519] are one of the most common representations for identity and access claims. For instance, they are used by the OpenID Connect and Secure Telephony Identity Revisited (STIR) standards. Also, JWTs are used by W3C's Verifiable Credentials and are used in many Decentralized Identity systems.¶
With these new use cases, there is an increased focus on adopting privacy-protecting cryptographic primitives. While such primitives are still an active area of academic and applied research, the leading candidates introduce new patterns that are not currently supported by JOSE. These new patterns are largely focused on two areas: supporting selective disclosure when presenting information, and minimizing correlation through the use of Zero-Knowledge Proofs (ZKPs) in addition to traditional signatures.¶
There are a growing number of these cryptographic primitives that support selective disclosure while protecting privacy across multiple presentations. Examples used in the context of Verifiable Credentials are:¶
All of these follow the same pattern of taking multiple claims (a.k.a., "attributes" or "messages" in the literature) and binding them together into a single issued token. These are then later securely one-way transformed into a presentation that reveals potentially only a subset of the original claims, predicate proofs about the claim values, or proofs of knowledge of the claims.¶
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 roles of "issuer", "holder", and "verifier", are used as defined by the Verifiable Credentials Data Model v1.1. The term "presentation" is also used as defined by this source, but the term "credential" is avoided in this specification in order to minimize confusion with other definitions.¶
A JSON Web Proof (JWP) is very similar to a JWS [RFC7515], with the addition that it can contain multiple individual secured payloads instead of a singular one. JWP-supporting algorithms are then able to separate and act on the individual payloads contained within.¶
The intent of JSON Web Proofs is to establish a common container format for multiple payloads that can be integrity-verified against a cryptographic proof value also in the container. It does not create or specify any cryptographic protocols, multi-party protocols, or detail any algorithm-specific capabilities.¶
In order to fully support the newer privacy primitives, JWP introduces the three roles of issuer, holder, and verifier as defined by the VC Data Model. There are also two forms of a JWP: the issued form created by an issuer for a holder, and the presented form created by a holder for a verifier.¶
A JWP is initially created by the issuer using the issue
interaction with an implementation. A successful result is an issued JWP that has a single issuer-protected header, one or more payloads, and an initial proof value that contains the issuing algorithm output. The holder, upon receiving an issued JWP, then uses confirm
to check the integrity protection of the header and all payloads using the given proof value.¶
After validation, the holder uses present
to apply any selective disclosure choices, perform privacy-preserving transformations for unlinkability, and add a presentation-protected header that ensures the resulting presented JWP cannot be replayed. The verifier then uses verify
to ensure the integrity protection of the protected headers and any disclosed payloads, along with verifying any additional ZKPs covering non-disclosed payloads.¶
While issue
and confirm
only occur when a JWP is initially created by the issuer, the present
and verify
steps may be safely repeated by a holder on an issued JWP. The unlinkability of the resulting presented JWP is only provided when supported by the underlying algorithm.¶
Algorithm definitions that support JWPs are being done in separate companion specifications - just as the JSON Web Algorithms [RFC7518] specification does for JWS and JWE [RFC7516]. The JSON Proof Algorithms specification defines how an initial set of algorithms are used with JWP.¶
A JWP is always in one of two forms, the issued form and the presented form. The significant difference between the two forms is the number of protected headers. An issued JWP has only one issuer protected header, while a presented JWP will have both the issuer protected header and an additional presentation protected header. Each protected headers is a JSON object that is serialized as a UTF-8 encoded octet string.¶
All JWP forms have one or more payloads; each payload is an octet string. The payloads are arranged in an array for which the ordering is preserved in all serializations.¶
The JWP proof value is a single octet string that is only generated from and processed by the underlying JPA. Internally, the proof value may contain one or more cryptographic statements that are used to check the integrity protection of the header(s) and all payloads. Each of these statements may be a ZKP or a traditional cryptographic signature. The algorithm is responsible for how these statements are serialized into a single proof value.¶
When a JWP is first created it is always in the issuer form. It will contain the issuer protected header along with all of the payloads.¶
The issued form can only be confirmed by a holder as being correctly formed and protected, it is NOT to be verified directly or presented as-is to a verifier. The holder SHOULD treat an issued JWP as private and use appropriately protected storage.¶
The issuer protected header applies to all of the payloads equally. It is recommended that any payload-specific information not be included in this header and instead be handled outside of the cryptographic envelope. This is to minimize any correlatable signals in the metadata, to reduce a verifier's ability to group different presentations based on small header variations from the same issuer.¶
Every issuer protected header MUST have, at minimum, an alg
value that identifies a valid JPA.¶
For example:¶
{ "alg":"BBS-X" }¶
Payloads are represented and processed as individual octet strings and arranged in an ordered array when there are multiple payloads. All application context of the placement and encoding of each payload value is out of scope of this specification and SHOULD be well defined and documented by the application or other specifications.¶
JPAs MAY provide software interfaces that perform the encoding of individual payloads which accept native inputs such as numbers, sets, or elliptic curve points. This enables the algorithm to support advanced features such as blinded values and predicate proofs. These interfaces would generate the octet string encoded payload value as well as include protection of that payload in the combined proof value.¶
The proof value is a binary octet string that is opaque to applications. Individual proof-supporting algorithms are responsible for the contents and security of the proof value, along with any required internal structures.¶
The issuer proof is only for the holder to perform validation, checking that the issuer header and all payloads are properly encoded and protected by the given proof.¶
When an issued JWP is presented, it undergoes a transformation that adds a presentation protected header. It may also have one or more payloads hidden, disclosing only a subset of the original issued payloads. The proof value will always be updated to add integrity protection of the presentation header along with the necessary cryptographic statements to verify the presented JWP.¶
When supported by the underling JPA, a single issued JWP can be used to safely generate multiple presented JWPs without becoming correlatable.¶
A JWP may also be single-use, where an issued JWP can only be used once to generate a presented form, any additional presentations would be inherently correlatable. These are still useful for applications needing only selective disclosure or where new unique issued JWPs can be retrieved easily.¶
The presented form of a JWP MUST contain a presentation protected header. It is added by the holder and MUST be integrity protected by the underling JPA.¶
This header is used to ensure a presented JWP can not be replayed and is cryptographically bound to the verifier it was presented to.¶
While there isn't any required values in the presentation header, it MUST contain one or more header values that uniquely identify the presented JWP to both the holder and verifier. For example, header values that would satisfy this requirement include nonce
and aud
.¶
Any one or more payloads may be non-disclosed in a presented JWP. When a payload is not disclosed, the position of other payloads does not change; the resulting array will simply be sparse and only contain the disclosed payloads.¶
The disclosed payloads will always be in the same array positions to preserve any index-based references by the application between the issued and presented forms of the JWP. How the sparse array is represented is specific to the serialization used.¶
Algorithms MAY support including a proof about a payload in the presentation. Applications then treat that proven payload the same as any other non-disclosed payload and not include it in the presented array of payloads.¶
The proof value of a presented JWP will always be different than the issued proof. At a minimum it MUST be updated to include protection of the added presentation header.¶
Algorithms SHOULD generate an un-correlatable presentation proof in order to support multiple presentations from a single issued JWP.¶
Any payload specific proofs are included in the single proof value for the presented JWP, the JPA is responsible for internally encoding multiple proof values into one and cryptographically binding them to a specific payload from the issuer.¶
Each disclosed payload MUST be base64url encoded when preparing it to be serialized. The headers and proof are also individually base64url encoded.¶
Like JWS, JWP supports both a Compact Serialization and a JSON Serialization.¶
The individually encoded payloads are concatenated with the ~
character to form an ordered delimited array. Any non-disclosed payloads are simply left blank, resulting in sequential ~~
characters such that all payload positions are preserved.¶
The headers, concatenated payloads, and proof value are then concatenated with a .
character to form the final compact serialization. The issued form will only contain one header and always have three .
separated parts. The presented form will always have four .
separated parts, the issued header, followed by the protected header, then the payloads and the proof.¶
Non-disclosed payloads in the JSON serialization are represented with a null
value in the payloads
array.¶
Example flattened JSON serialization showing the presentation form with both the issuer and presentation headers along with the first and third payloads hidden.¶
Notes to be expanded:¶
This document has no IANA actions.¶
The following examples use algorithms defined in JSON Proof Algorithms and also contain the keys used, so that implementations can validate these samples.¶
This example uses the Single-Use Algorithm as defined in JSON Proof Algorithms to create a JSON Proof Token. It demonstrates how to apply selective disclosure using an array of traditional JWS-based signatures. Unlinkability is only achieved by using each JWP one time, as multiple uses are inherently linkable via the traditional ECDSA signature embedded in the proof.¶
To begin we need two asymmetric keys for Single-Use, one that represents the JPT signers's stable key, and the other is an ephemeral key generated by the Signer just for this JWP.¶
This is the Signer's stable private key used in this example in the JWK format:¶
This is the ephemeral private key used in this example in the JWK format:¶
This is the Holder's presentation private key used in this example in the JWK format:¶
The JWP Protected Header declares that the data structure is a JPT and the JWP Proof Input is secured using the Single-Use ECDSA algorithm with the P-256 curve and SHA-256 digest. It also includes the ephemeral public key, the Holder's presentation public key and list of claims used for this JPT.¶
After removing formatting whitespace, the octets representing UTF8(JWP Protected Header) in this example (using JSON array notation) are:¶
Encoding this JWP Protected Header as BASE64URL(UTF8(JWP Protected Header)) gives this value:¶
Each payload must also be individually encoded:¶
The first payload is the string "Doe"
with the octet sequence of [ 34, 68, 111, 101, 34 ]
and base64url-encoded as IkRvZSI
.¶
The second payload is the string "Jay"
with the octet sequence of [ 34, 74, 97, 121, 34 ]
and base64url-encoded as IkpheSI
.¶
The third payload is the string "jaydoe@example.org"
with the octet sequence of [ 34, 106, 97, 121, 100, 111, 101, 64, 101, 120, 97, 109, 112, 108, 101, 46, 111, 114, 103, 34 ]
and base64url-encoded as ImpheWRvZUBleGFtcGxlLm9yZyI
.¶
The fourth payload is the string 42
with the octet sequence of [52, 50]
and base64url-encoded as NDI
.¶
The Single Use algorithm utilizes multiple individual JWS Signatures. Each signature value is generated by creating a JWS with a single Protected Header with the associated alg
value, in this example the fixed header used for each JWS is the serialized JSON Object {"alg":"ES256"}
. The JWS payload for each varies and the resulting signature value is used in its unencoded form (the octet string, not the base64url-encoded form).¶
The first signature is generated by creating a JWS using the fixed header with the payload set to the octet string of the JPT protected header from earlier. The resulting JWS signature using the Signer's stable key is the octet string of:¶
This process is repeated for the JPT payloads, using their octet strings as the payload in the ephemeral JWS in order to generate a signature using the epehemeral key for each:¶
The first payload signature is:¶
The second payload signature is:¶
The third payload signature is:¶
The fourth payload signature is:¶
Each payload's individual signature is concatenated in order, resulting in a larger octet string with a length of an individual signature (64 octets for ES256) multiplied by the number of payloads (4 for this example). These payload ephemeral signatures are then appended to the initial protected header stable signature. Using the above examples, the resulting octet string is 320 in length (5 * 64
):¶
The final Proof value from the Signer is the concatenated array of the header signature followed by all of the payload signatures, then base64url encoded.¶
The resulting JSON serialized JPT using the above examples is:¶
The compact serialization of the same JPT is:¶
To present this JPT, we first use the following presentation header with a nonce (provided by the Verifier):¶
Which when serialized results in the following octets:¶
And when base64url encoded results in the string:¶
When signed with the holder's presentation key, the resulting signature octets are:¶
Then by applying selective disclosure of only the given name and age claims (family name and email hidden), the proof value including the signature of the presentation header and removing the ephemeral signatures of the family name and email payloads results in the following octet array:¶
The resulting presented JPT in JSON serialization:¶
And also in compact serialization:¶
See JPA BBS-X example.¶