Internet-Draft | SD-JWT | March 2023 |
Fett, et al. | Expires 14 September 2023 | [Page] |
This document specifies conventions for creating JSON Web Token (JWT) documents that support selective disclosure of JWT claims.¶
This note is to be removed before publishing as an RFC.¶
Discussion of this document takes place on the Web Authorization Protocol Working Group mailing list (oauth@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/oauth/.¶
Source for this draft and an issue tracker can be found at https://github.com/oauth-wg/oauth-selective-disclosure-jwt.¶
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 14 September 2023.¶
Copyright (c) 2023 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 JSON-based [RFC8259] representation of claims in a signed JSON Web Token (JWT) [RFC7519] is secured against modification using JSON Web Signature (JWS) [RFC7515] digital signatures. A consumer of a signed JWT that has checked the signature can safely assume that the contents of the token have not been modified. However, anyone receiving an unencrypted JWT can read all the claims. Likewise, anyone with the decryption key receiving encrypted JWT can also read all the claims.¶
One of the common use cases of a signed JWT is representing a user's identity. As long as the signed JWT is one-time use, it typically only contains those claims the user has consented to disclose to a specific Verifier. However, there is an increasing number of use cases where a signed JWT is created once and then used a number of times by the user (the "Holder" of the JWT). In such use cases, the signed JWT needs to contain the superset of all claims the user of the signed JWT might want to disclose to Verifiers at some point. The ability to selectively disclose a subset of these claims depending on the Verifier becomes crucial to ensure minimum disclosure and prevent Verifiers from obtaining claims irrelevant for the transaction at hand. SD-JWTs defined in this document enable such selective disclosure of JWT claims.¶
One example of a multi-use JWT is a verifiable credential, an issuer-signed credential that contains the claims about a subject, and whose authenticity can be cryptographically verified.¶
Similar to the JWT specification on which it builds, this document is a product of the Web Authorization Protocol (oauth) working group. However, while both JWT and SD-JWT have potential OAuth 2.0 applications, their utility and application is certainly not constrained to OAuth 2.0. JWT was developed as a general-purpose token format and has seen widespread usage in a variety of applications. SD-JWT is a selective disclosure mechanism for JWT and is similarly intended to be general-purpose specification.¶
While JWTs for claims describing natural persons are a common use case, the mechanisms defined in this document can be used for other use cases as well.¶
In an Issuer-signed SD-JWT, claims can be hidden, but cryptographically protected against undetected modification. When issuing the SD-JWT to the Holder, the Issuer also sends the cleartext counterparts of all hidden claims, the so-called Disclosures, separate from the SD-JWT itself.¶
The Holder decides which claims to disclose to a Verifier and forwards the respective Disclosures together with the SD-JWT to the Verifier. The Verifier has to verify that all disclosed claim values were part of the original, Issuer-signed SD-JWT. The Verifier will not, however, learn any claim values not disclosed in the Disclosures.¶
This document also describes an optional mechanism for Holder Binding, or the concept of binding an SD-JWT to key material controlled by the Holder. The strength of the Holder Binding is conditional upon the trust in the protection of the private key of the key pair an SD-JWT is bound to.¶
SD-JWT can be used with any JSON-based representation of claims, including JSON-LD.¶
This specification aims to be easy to implement and to leverage established and widely used data formats and cryptographic algorithms wherever possible.¶
This specification defines¶
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.¶
base64url denotes the URL-safe base64 encoding without padding defined in Section 2 of [RFC7515].¶
Note: discuss if we want to include Client, Authorization Server for the purpose of ensuring continuity and separating the entity from the actor.¶
This section describes SD-JWTs and Disclosures at a conceptual level, abstracting from the data formats described in Section 5.¶
An SD-JWT, at its core, is a digitally signed JSON document containing digests over the selectively disclosable claims with the Disclosures outside the document.¶
Each digest value ensures the integrity of, and maps to, the respective Disclosure. Digest values are calculated using a hash function over the Disclosures, each of which contains the claim name, the claim value, and a random salt. The Disclosures are sent to the Holder together with the SD-JWT in the Combined Format for Issuance defined in Section 5.3.¶
An SD-JWT MAY also contain clear-text claims that are always disclosed to the Verifier.¶
To disclose to a Verifier a subset of the SD-JWT claim values, a Holder sends only the Disclosures of those selectively released claims to the Verifier along with the SD-JWT in the Combined Format for Presentation defined in Section 5.4.¶
Holder Binding is an optional feature. For example, when Cryptographic Holder Binding is required by the use-case, the SD-JWT must contain information about the key material controlled by the Holder.¶
Note: How the public key is included in SD-JWT is out of scope of this document. It can be passed by value or by reference.¶
The Holder can then create a signed document, the Holder Binding JWT, using its private key. This document contains some data provided by the Verifier (out of scope of this document) to ensure the freshness of the signature, for example, a nonce and an indicator of the intended audience for the document.¶
The Holder Binding JWT can be included in the Combined Format for Presentation and sent to the Verifier along with the SD-JWT and the Holder-Selected Disclosures.¶
Note that there may be other ways to send the Holder Binding JWT to the Verifier or to prove Holder Binding. In these cases, inclusion of the Holder Binding JWT in the Combined Format for Presentation is not required.¶
At a high level, the Verifier¶
The detailed algorithm is described in Section 6.2.¶
This section defines data formats for SD-JWTs, Disclosures, Holder Binding JWTs and formats for combining these elements for transport.¶
An SD-JWT is a JWT that MUST be signed using the Issuer's private key. The
payload of an SD-JWT MUST contain the _sd_alg
claim
described in Section 5.1.2. The SD-JWT payload MAY contain one or more selectively disclosable claims. It MAY also contain a Holder's public key or a reference
thereto, as well as further claims such as iss
, iat
, etc. as defined or
required by the application using SD-JWTs.¶
For each claim that is to be selectively disclosed, the Issuer creates a Disclosure, hashes it, and includes the hash instead of the original claim in the SD-JWT, as described next. The Disclosures are then sent to the Holder.¶
The Issuer MUST create a Disclosure for each selectively disclosable claim as follows:¶
Create an array of three elements in this order:¶
The order is decided based on the readability considerations: salts would have a constant length within the SD-JWT, claim names would be around the same length all the time, and claim values would vary in size, potentially being large objects.¶
The following example illustrates the steps described above.¶
The array is created as follows:¶
["_26bc4LT-ac6q2KI6cBW5es", "family_name", "Möbius"]¶
The resulting Disclosure would be: WyJfMjZiYzRMVC1hYzZxMktJNmNCVzVlcyIsICJmYW1pbHlfbmFtZSIsICJNw7ZiaXVzIl0
¶
Note that the JSON encoding of the object is not canonicalized, so variations in white space, encoding of Unicode characters, and ordering of object properties are allowed. For example, the following strings are all valid and encode the same claim value:¶
¨
placed over the letter): WyJfMjZiYzRMVC1hYzZxMktJNmNCVzVlcyIsICJmYW1pbHlfbmFtZSIsICJNXHUwMGY2Yml1cyJd
¶
WyJfMjZiYzRMVC1hYzZxMktJNmNCVzVlcyIsImZhbWlseV9uYW1lIiwiTcO2Yml1cyJd
¶
WwoiXzI2YmM0TFQtYWM2cTJLSTZjQlc1ZXMiLAoiZmFtaWx5X25hbWUiLAoiTcO2Yml1cyIKXQ
¶
See Appendix B for some further considerations on the Disclosure format approach.¶
For embedding the Disclosures in the SD-JWT, the Disclosures are hashed using the hash algorithm specified in the _sd_alg
claim described in Section 5.1.2. The resulting digest is then included in the SD-JWT instead of the original claim value, as described next.¶
The digest MUST be taken over the US-ASCII bytes of the base64url-encoded Disclosure. This follows the convention in JWS [RFC7515] and JWE [RFC7516]. The bytes of the digest MUST then be base64url-encoded.¶
It is important to note that:¶
For example, the
SHA-256 digest of the Disclosure WyI2cU1RdlJMNWhhaiIsICJmYW1pbHlfbmFtZSIsICJNw7ZiaXVzIl0
would be
uutlBuYeMDyjLLTpf6Jxi7yNkEF35jdyWMn9U7b_RYY
.¶
An Issuer MAY add additional digests to the SD-JWT that are not associated with any claim. The purpose of such "decoy" digests is to make it more difficult for an attacker to see the original number of claims contained in the SD-JWT. It is RECOMMENDED to create the decoy digests by hashing over a cryptographically secure random number. The bytes of the digest MUST then be base64url-encoded as above. The same digest function as for the Disclosures MUST be used.¶
For decoy digests, no Disclosure is sent to the Holder, i.e., the Holder will see digests that do not correspond to any Disclosure. See Section 9.3 for additional privacy considerations.¶
To ensure readability and replicability, the examples in this specification do not contain decoy digests unless explicitly stated.¶
An SD-JWT is a JWT that MUST be signed using the Issuer's private key.
It MUST use a JWS asymmetric digital signature algorithm. It
MUST NOT use none
or an identifier for a symmetric algorithm (MAC).¶
An SD-JWT MAY contain both selectively disclosable claims and non-selectively disclosable claims, i.e., claims that are always contained in the SD-JWT in plaintext and are always visible to a Verifier.¶
It is the Issuer who decides which claims are selectively disclosable and which are not. However, claims controlling the validity of the SD-JWT, such as iss
, exp
, or nbf
are usually included in plaintext. End-User claims MAY be included as plaintext as well, e.g., if hiding the particular claims from the Verifier does not make sense in the intended use case.¶
Claims that are not selectively disclosable are included in the SD-JWT in plaintext just as they would be in any other JWT.¶
Selectively disclosable claims are omitted from the SD-JWT. Instead, the digests of the respective Disclosures and potentially decoy digests are contained as an array in a new JWT claim, _sd
.¶
The _sd
key MUST refer to an array of strings, each string being a digest of a Disclosure or a decoy digest as described above.¶
The array MAY be empty in case the Issuer decided not to selectively disclose any of the claims at that level. However, it is RECOMMENDED to omit the _sd
key in this case to save space.¶
The Issuer MUST hide the original order of the claims in the array. To ensure this, it is RECOMMENDED to shuffle the array of hashes, e.g., by sorting it alphanumerically or randomly. The precise method does not matter as long as it does not depend on the original order of elements.¶
Issuers MUST NOT issue SD-JWTs where¶
Being JSON, an object in an SD-JWT payload MAY contain key-value pairs where the value is another object. In SD-JWT, the Issuer decides for each key individually, on each level of the JSON, whether the key should be selectively disclosable or not. This choice can be made on each level independent from whether keys higher in the hierarchy are selectively disclosable.¶
For any selectively disclosable claim, the _sd
key containing the digest value MUST be included in the SD-JWT at the same level as the original claim. It follows that the _sd
key MAY appear multiple times in an SD-JWT. It MAY even appear within Disclosures.¶
The following examples illustrate some of the options an Issuer has. It is up to the Issuer to decide which option to use, depending on, for example, the expected use cases for the SD-JWT, requirements for privacy, size considerations, or ecosystem requirements.¶
The following claim set is used as an example throughout this section:¶
{ "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "address": { "street_address": "Schulstr. 12", "locality": "Schulpforta", "region": "Sachsen-Anhalt", "country": "DE" } }¶
Important: Throughout the examples in this document, line breaks had to be added to JSON strings and base64-encoded strings (as shown in the next example) to adhere to the 72 character limit for lines in RFCs and for readability. JSON does not allow line breaks in strings.¶
The Issuer can decide to treat the address
claim as a block that can either be disclosed completely or not at all. The following example shows that in this case, the entire address
claim is treated as an object in the Disclosure.¶
{ "_sd": [ "FphFFpj1vtr0rpYK-14fickGKMg3zf1fIpJXxTK8PAE" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "_sd_alg": "sha-256" }¶
The Issuer would create the following Disclosure:¶
Disclosure for address
:¶
SHA-256 Hash: FphFFpj1vtr0rpYK-14fickGKMg3zf1fIpJXxTK8PAE
¶
Disclosure:¶
WyJpbVFmR2oxX00wRWw3NmtkdmY3RGF3IiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRy ZXNzIjogIlNjaHVsc3RyLiAxMiIsICJsb2NhbGl0eSI6ICJTY2h1bHBmb3J0YSIsICJy ZWdpb24iOiAiU2FjaHNlbi1BbmhhbHQiLCAiY291bnRyeSI6ICJERSJ9XQ¶
Contents:¶
["imQfGj1_M0El76kdvf7Daw", "address", {"street_address": "Schulstr. 12", "locality": "Schulpforta", "region": "Sachsen-Anhalt", "country": "DE"}]¶
The Issuer may instead decide to make the address
claim contents selectively disclosable individually:¶
{ "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "address": { "_sd": [ "G_FeM1D-U3tDJcHB7pwTNEElLal9FE9PUs0klHgeM1c", "KlG6HEM6XWbymEJDfyDY4klJkQQ9iTuNG0LQXnE9mQ0", "X96Emv4S9uzFUGkU8MmOlFzUwEtDNeT-ToXw3Fx9AfI", "ffPGyxFBnNA1r60g2f796Hqq3dBGtaOogpnIBgRGdyY" ] }, "_sd_alg": "sha-256" }¶
In this case, the Issuer would use the following data in the Disclosures for the address
sub-claims:¶
Disclosure for street_address
:¶
SHA-256 Hash: G_FeM1D-U3tDJcHB7pwTNEElLal9FE9PUs0klHgeM1c
¶
Disclosure:¶
WyJRU05JaHVfbjZhMXJJOF8yZU5BUkNRIiwgInN0cmVldF9hZGRyZXNzIiwgIlNjaHVs c3RyLiAxMiJd¶
Contents:¶
["QSNIhu_n6a1rI8_2eNARCQ", "street_address", "Schulstr. 12"]¶
Disclosure for locality
:¶
SHA-256 Hash: KlG6HEM6XWbymEJDfyDY4klJkQQ9iTuNG0LQXnE9mQ0
¶
Disclosure:¶
WyJRUGtibHhUbmJTTEw5NEkyZlpJYkhBIiwgImxvY2FsaXR5IiwgIlNjaHVscGZvcnRh Il0¶
Contents:¶
["QPkblxTnbSLL94I2fZIbHA", "locality", "Schulpforta"]¶
Disclosure for region
:¶
SHA-256 Hash: ffPGyxFBnNA1r60g2f796Hqq3dBGtaOogpnIBgRGdyY
¶
Disclosure:¶
WyJqUi1ZZWQwOEFFbzRnY29ncFQ1X1VBIiwgInJlZ2lvbiIsICJTYWNoc2VuLUFuaGFs dCJd¶
Contents:¶
["jR-Yed08AEo4gcogpT5_UA", "region", "Sachsen-Anhalt"]¶
Disclosure for country
:¶
SHA-256 Hash: X96Emv4S9uzFUGkU8MmOlFzUwEtDNeT-ToXw3Fx9AfI
¶
Disclosure:¶
WyJ5djNBblV6ODgtQUx3VjhISld6bi1nIiwgImNvdW50cnkiLCAiREUiXQ¶
Contents:¶
["yv3AnUz88-ALwV8HJWzn-g", "country", "DE"]¶
The Issuer may also make one sub-claim of address
non-selectively disclosable and hide only the other sub-claims:¶
{ "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "address": { "_sd": [ "7rFDQjONCu_2unNkUT3DwzhmJXf0aaczX0ehGePLpII", "NHVLP1NoyICWhfr890M8KbLCA_mm9B2SrT_MpyluyeA", "XhaM20bv5qdxmIE8FGf1Jl3R2xe_lOxjh7ig_0Sd_kg" ], "country": "DE" }, "_sd_alg": "sha-256" }¶
There would be no Disclosure for country
in this case.¶
The Issuer may also decide to make the address
claim contents selectively disclosable recursively, i.e., the address
claim is made selectively disclosable as well as its sub-claims:¶
{ "_sd": [ "Lot9gM9VOOiyFS4FOR1ykwz-V-fB_xwF63jWemIH4d0" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "_sd_alg": "sha-256" }¶
The Issuer creates Disclosures first for the sub-claims and then includes their digests in the Disclosure for the address
claim:¶
Disclosure for street_address
:¶
SHA-256 Hash: udFWFx_91NgCjhLTHJAvvAHwNT2vlHBsWxPIOxK2Ydo
¶
Disclosure:¶
WyIyUzBkSXhpSE9CblVldFBKMW5GbERBIiwgInN0cmVldF9hZGRyZXNzIiwgIlNjaHVs c3RyLiAxMiJd¶
Contents:¶
["2S0dIxiHOBnUetPJ1nFlDA", "street_address", "Schulstr. 12"]¶
Disclosure for locality
:¶
SHA-256 Hash: 1zgsu9Fe6bkbQY9zJsfPTo1uBPMVl48m4EafxJTYSu0
¶
Disclosure:¶
WyI5YU9BQzFHNHZlNFJjalJvTUtERWNnIiwgImxvY2FsaXR5IiwgIlNjaHVscGZvcnRh Il0¶
Contents:¶
["9aOAC1G4ve4RcjRoMKDEcg", "locality", "Schulpforta"]¶
Disclosure for region
:¶
SHA-256 Hash: DKtN_qW_hayYCGCKihS39M3sobs1RTekxaKnMbE17-Q
¶
Disclosure:¶
WyJqdkZ5QUxBaGFaa0hBU0tCYUZqMGJBIiwgInJlZ2lvbiIsICJTYWNoc2VuLUFuaGFs dCJd¶
Contents:¶
["jvFyALAhaZkHASKBaFj0bA", "region", "Sachsen-Anhalt"]¶
Disclosure for country
:¶
SHA-256 Hash: h2DxxE80C7qRWxCQjwR96da46jr2B8bLSRwAdbZSRlo
¶
Disclosure:¶
WyI0dGNmbFJNZWdxUG54ZzZTUkQ2ZzBnIiwgImNvdW50cnkiLCAiREUiXQ¶
Contents:¶
["4tcflRMegqPnxg6SRD6g0g", "country", "DE"]¶
Disclosure for address
:¶
SHA-256 Hash: Lot9gM9VOOiyFS4FOR1ykwz-V-fB_xwF63jWemIH4d0
¶
Disclosure:¶
WyJGcDBqLTd6Q2FOVFdmX3dLNjdzeGlnIiwgImFkZHJlc3MiLCB7Il9zZCI6IFsiMXpn c3U5RmU2YmtiUVk5ekpzZlBUbzF1QlBNVmw0OG00RWFmeEpUWVN1MCIsICJES3ROX3FX X2hheVlDR0NLaWhTMzlNM3NvYnMxUlRla3hhS25NYkUxNy1RIiwgImgyRHh4RTgwQzdx Uld4Q1Fqd1I5NmRhNDZqcjJCOGJMU1J3QWRiWlNSbG8iLCAidWRGV0Z4XzkxTmdDamhM VEhKQXZ2QUh3TlQydmxIQnNXeFBJT3hLMllkbyJdfV0¶
Contents:¶
["Fp0j-7zCaNTWf_wK67sxig", "address", {"_sd": ["1zgsu9Fe6bkbQY9zJsfPTo1uBPMVl48m4EafxJTYSu0", "DKtN_qW_hayYCGCKihS39M3sobs1RTekxaKnMbE17-Q", "h2DxxE80C7qRWxCQjwR96da46jr2B8bLSRwAdbZSRlo", "udFWFx_91NgCjhLTHJAvvAHwNT2vlHBsWxPIOxK2Ydo"]}]¶
The claim _sd_alg
indicates the hash algorithm
used by the Issuer to generate the digests over the salts and the
claim values. If the _sd_alg
claim is not present, a default value of sha-256
is used.¶
The hash algorithm identifier MUST be a hash algorithm value from the "Hash Name String" column in the IANA "Named Information Hash Algorithm" registry [IANA.Hash.Algorithms] or a value defined in another specification and/or profile of this specification.¶
To promote interoperability, implementations MUST support the sha-256
hash algorithm.¶
See Section 8 for requirements regarding entropy of the salt, minimum length of the salt, and choice of a hash algorithm.¶
If the Issuer wants to enable Holder Binding, it MAY include a public key associated with the Holder, or a reference thereto.¶
It is out of the scope of this document to describe how the Holder key pair is established. For example, the Holder MAY provide a key pair to the Issuer, the Issuer MAY create the key pair for the Holder, or Holder and Issuer MAY use pre-established key material.¶
Note: Examples in this document use cnf
Claim defined in [RFC7800] to include raw public key by value in SD-JWT.¶
This example uses the following object as the set of claims that the Issuer is issuing:¶
{ "sub": "john_doe_42", "given_name": "John", "family_name": "Doe", "email": "johndoe@example.com", "phone_number": "+1-202-555-0101", "address": { "street_address": "123 Main St", "locality": "Anytown", "region": "Anystate", "country": "US" }, "birthdate": "1940-01-01" }¶
The following non-normative example shows the payload of an SD-JWT. The Issuer
is using a flat structure in this case, i.e., all of the claims in the address
claim can only
be disclosed in full.¶
{ "_sd": [ "5nXy0Z3QiEba1V1lJzeKhAOGQXFlKLIWCLlhf_O-cmo", "9gZhHAhV7LZnOFZq_q7Fh8rzdqrrNM-hRWsVOlW3nuw", "S-JPBSkvqliFv1__thuXt3IzX5B_ZXm4W2qs4BoNFrA", "bviw7pWAkbzI078ZNVa_eMZvk0tdPa5w2o9R3Zycjo4", "o-LBCDrFF6tC9ew1vAlUmw6Y30CHZF5jOUFhpx5mogI", "pzkHIM9sv7oZH6YKDsRqNgFGLpEKIj3c5G6UKaTsAjQ", "rnAzCT6DTy4TsX9QCDv2wwAE4Ze20uRigtVNQkA52X0" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "_sd_alg": "sha-256", "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc", "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ" } } }¶
The SD-JWT is then signed by the Issuer to create a JWT like the following:¶
eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIjVuWHkwWjNRaUViYTFWMWxKemVLaEFPR 1FYRmxLTElXQ0xsaGZfTy1jbW8iLCAiOWdaaEhBaFY3TFpuT0ZacV9xN0ZoOHJ6ZHFyc k5NLWhSV3NWT2xXM251dyIsICJTLUpQQlNrdnFsaUZ2MV9fdGh1WHQzSXpYNUJfWlhtN FcycXM0Qm9ORnJBIiwgImJ2aXc3cFdBa2J6STA3OFpOVmFfZU1admswdGRQYTV3Mm85U jNaeWNqbzQiLCAiby1MQkNEckZGNnRDOWV3MXZBbFVtdzZZMzBDSFpGNWpPVUZocHg1b W9nSSIsICJwemtISU05c3Y3b1pINllLRHNScU5nRkdMcEVLSWozYzVHNlVLYVRzQWpRI iwgInJuQXpDVDZEVHk0VHNYOVFDRHYyd3dBRTRaZTIwdVJpZ3RWTlFrQTUyWDAiXSwgI mlzcyI6ICJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsICJpYXQiOiAxNTE2MjM5M DIyLCAiZXhwIjogMTczNTY4OTY2MSwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiO iB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSM TladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV 1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.D7zXHQgMee BXNTiCmfq1SVRkixyj4mpZoxCLcuibWxa_eixmr5B-g-DPAY93k2rs1-PqSD5aKrqwHs rg_p2lRw¶
The Issuer creates the following Disclosures:¶
Disclosure for sub
:¶
SHA-256 Hash: pzkHIM9sv7oZH6YKDsRqNgFGLpEKIj3c5G6UKaTsAjQ
¶
Disclosure:¶
WyJyU0x1em5oaUxQQkRSWkUxQ1o4OEtRIiwgInN1YiIsICJqb2huX2RvZV80MiJd¶
Contents:¶
["rSLuznhiLPBDRZE1CZ88KQ", "sub", "john_doe_42"]¶
Disclosure for given_name
:¶
SHA-256 Hash: S-JPBSkvqliFv1__thuXt3IzX5B_ZXm4W2qs4BoNFrA
¶
Disclosure:¶
WyJhYTFPYmdlUkJnODJudnpMYnRQTklRIiwgImdpdmVuX25hbWUiLCAiSm9obiJd¶
Contents:¶
["aa1ObgeRBg82nvzLbtPNIQ", "given_name", "John"]¶
Disclosure for family_name
:¶
SHA-256 Hash: o-LBCDrFF6tC9ew1vAlUmw6Y30CHZF5jOUFhpx5mogI
¶
Disclosure:¶
WyI2VWhsZU5HUmJtc0xDOFRndTh2OFdnIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd¶
Contents:¶
["6UhleNGRbmsLC8Tgu8v8Wg", "family_name", "Doe"]¶
Disclosure for email
:¶
SHA-256 Hash: bviw7pWAkbzI078ZNVa_eMZvk0tdPa5w2o9R3Zycjo4
¶
Disclosure:¶
WyJ2S0t6alFSOWtsbFh2OWVkNUJ1ZHZRIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBs ZS5jb20iXQ¶
Contents:¶
["vKKzjQR9kllXv9ed5BudvQ", "email", "johndoe@example.com"]¶
Disclosure for phone_number
:¶
SHA-256 Hash: 9gZhHAhV7LZnOFZq_q7Fh8rzdqrrNM-hRWsVOlW3nuw
¶
Disclosure:¶
WyJVZEVmXzY0SEN0T1BpZDRFZmhPQWNRIiwgInBob25lX251bWJlciIsICIrMS0yMDIt NTU1LTAxMDEiXQ¶
Contents:¶
["UdEf_64HCtOPid4EfhOAcQ", "phone_number", "+1-202-555-0101"]¶
Disclosure for address
:¶
SHA-256 Hash: 5nXy0Z3QiEba1V1lJzeKhAOGQXFlKLIWCLlhf_O-cmo
¶
Disclosure:¶
WyJOYTNWb0ZGblZ3MjhqT0FyazdJTlZnIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRy ZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9u IjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0¶
Contents:¶
["Na3VoFFnVw28jOArk7INVg", "address", {"street_address": "123 Main St", "locality": "Anytown", "region": "Anystate", "country": "US"}]¶
Disclosure for birthdate
:¶
SHA-256 Hash: rnAzCT6DTy4TsX9QCDv2wwAE4Ze20uRigtVNQkA52X0
¶
Disclosure:¶
WyJkQW9mNHNlZTFGdDBXR2dHanVjZ2pRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAx Il0¶
Contents:¶
["dAof4see1Ft0WGgGjucgjQ", "birthdate", "1940-01-01"]¶
Besides the SD-JWT itself, the Holder needs to learn the raw claim values that are contained in the SD-JWT, along with the precise input to the digest calculation and the salts. To this end, the Issuer sends the Disclosure objects that were also used for the hash calculation, as described in Section 5.1.1.1, to the Holder.¶
The data format for sending the SD-JWT and the Disclosures to the Holder MUST be a series of base64url-encoded values, each separated from the next by a single tilde ('~') character as follows:¶
<SD-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>¶
The order of the base64url-encoded values MUST be an SD-JWT followed by the Disclosures.¶
This is called the Combined Format for Issuance.¶
The Disclosures and SD-JWT are implicitly linked through the digest values of the Disclosures included in the SD-JWT.¶
For Example 1, the Combined Format for Issuance looks as follows:¶
eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIjVuWHkwWjNRaUViYTFWMWxKemVLaEFPR 1FYRmxLTElXQ0xsaGZfTy1jbW8iLCAiOWdaaEhBaFY3TFpuT0ZacV9xN0ZoOHJ6ZHFyc k5NLWhSV3NWT2xXM251dyIsICJTLUpQQlNrdnFsaUZ2MV9fdGh1WHQzSXpYNUJfWlhtN FcycXM0Qm9ORnJBIiwgImJ2aXc3cFdBa2J6STA3OFpOVmFfZU1admswdGRQYTV3Mm85U jNaeWNqbzQiLCAiby1MQkNEckZGNnRDOWV3MXZBbFVtdzZZMzBDSFpGNWpPVUZocHg1b W9nSSIsICJwemtISU05c3Y3b1pINllLRHNScU5nRkdMcEVLSWozYzVHNlVLYVRzQWpRI iwgInJuQXpDVDZEVHk0VHNYOVFDRHYyd3dBRTRaZTIwdVJpZ3RWTlFrQTUyWDAiXSwgI mlzcyI6ICJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsICJpYXQiOiAxNTE2MjM5M DIyLCAiZXhwIjogMTczNTY4OTY2MSwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiO iB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSM TladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV 1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.D7zXHQgMee BXNTiCmfq1SVRkixyj4mpZoxCLcuibWxa_eixmr5B-g-DPAY93k2rs1-PqSD5aKrqwHs rg_p2lRw~WyJyU0x1em5oaUxQQkRSWkUxQ1o4OEtRIiwgInN1YiIsICJqb2huX2RvZV8 0MiJd~WyJhYTFPYmdlUkJnODJudnpMYnRQTklRIiwgImdpdmVuX25hbWUiLCAiSm9obi Jd~WyI2VWhsZU5HUmJtc0xDOFRndTh2OFdnIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~ WyJ2S0t6alFSOWtsbFh2OWVkNUJ1ZHZRIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBs ZS5jb20iXQ~WyJVZEVmXzY0SEN0T1BpZDRFZmhPQWNRIiwgInBob25lX251bWJlciIsI CIrMS0yMDItNTU1LTAxMDEiXQ~WyJOYTNWb0ZGblZ3MjhqT0FyazdJTlZnIiwgImFkZH Jlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5Ij ogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV 0~WyJkQW9mNHNlZTFGdDBXR2dHanVjZ2pRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLT AxIl0¶
(Line breaks for presentation only.)¶
For presentation to a Verifier, the Holder sends the SD-JWT and a selected subset of the Disclosures to the Verifier.¶
The data format for sending the SD-JWT and the Disclosures to the Verifier MUST be a series of base64url-encoded values, each separated from the next by a single tilde ('~') character as follows:¶
<SD-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure M>~<optional Holder Binding JWT>¶
The order of the base64url-encoded values MUST be an SD-JWT, Disclosures, and an optional Holder Binding JWT. In case there is no Holder Binding JWT, the last element MUST be an empty string. The last separating tilde character MUST NOT be omitted.¶
This is called the Combined Format for Presentation.¶
The Holder MAY send any subset of the Disclosures to the Verifier, i.e., none, multiple, or all Disclosures. For data that the Holder does not want to reveal to the Verifier, the Holder MUST NOT send Disclosures or reveal the salt values in any other way.¶
A Holder MUST NOT send a Disclosure that was not included in the SD-JWT or send a Disclosure more than once.¶
The Holder MAY add an optional JWT to prove Holder Binding to the Verifier.
The precise contents of the JWT are out of scope of this specification.
Usually, a nonce
and aud
claim are included to show that the proof is
intended for the Verifier and to prevent replay attacks. How the nonce
or
other claims are obtained by the Holder is out of scope of this specification.¶
Example Holder Binding JWT payload:¶
{ "nonce": "XZOUco1u_gEPknxS78sWWg", "aud": "https://example.com/verifier", "iat": 1677838084 }¶
Which is then signed by the Holder to create a JWT like the following:¶
eyJhbGciOiAiRVMyNTYifQ.eyJub25jZSI6ICJYWk9VY28xdV9nRVBrbnhTNzhzV1dnI iwgImF1ZCI6ICJodHRwczovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgImlhdCI6IDE2N zc4MzgwODR9.9yDey7Mo8ZBljM31FKpzGROJwKZbsxPlNl1B8l4y820bDEOnUL7AhzZj GJFBaUrPkrWVtWP0FO4FcB44Ma0LDg¶
Whether to require Holder Binding is up to the Verifier's policy, based on the set of trust requirements such as trust frameworks it belongs to.¶
Other ways of proving Holder Binding MAY be used when supported by the Verifier, e.g., when the Combined Format for Presentation without a Holder Binding JWT is itself embedded in a signed JWT. See Section 7 for details.¶
If no Holder Binding JWT is included, the Combined Format for Presentation ends with
the ~
character after the last Disclosure.¶
The following is a non-normative example of the contents of a Presentation for Example 1, disclosing
the claims given_name
, family_name
, and address
, as it would be sent from the Holder to the Verifier. The Holder Binding JWT as shown before is included as the last element.¶
eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIjVuWHkwWjNRaUViYTFWMWxKemVLaEFPR 1FYRmxLTElXQ0xsaGZfTy1jbW8iLCAiOWdaaEhBaFY3TFpuT0ZacV9xN0ZoOHJ6ZHFyc k5NLWhSV3NWT2xXM251dyIsICJTLUpQQlNrdnFsaUZ2MV9fdGh1WHQzSXpYNUJfWlhtN FcycXM0Qm9ORnJBIiwgImJ2aXc3cFdBa2J6STA3OFpOVmFfZU1admswdGRQYTV3Mm85U jNaeWNqbzQiLCAiby1MQkNEckZGNnRDOWV3MXZBbFVtdzZZMzBDSFpGNWpPVUZocHg1b W9nSSIsICJwemtISU05c3Y3b1pINllLRHNScU5nRkdMcEVLSWozYzVHNlVLYVRzQWpRI iwgInJuQXpDVDZEVHk0VHNYOVFDRHYyd3dBRTRaZTIwdVJpZ3RWTlFrQTUyWDAiXSwgI mlzcyI6ICJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsICJpYXQiOiAxNTE2MjM5M DIyLCAiZXhwIjogMTczNTY4OTY2MSwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiO iB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSM TladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV 1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.D7zXHQgMee BXNTiCmfq1SVRkixyj4mpZoxCLcuibWxa_eixmr5B-g-DPAY93k2rs1-PqSD5aKrqwHs rg_p2lRw~WyJOYTNWb0ZGblZ3MjhqT0FyazdJTlZnIiwgImFkZHJlc3MiLCB7InN0cmV ldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCA icmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJhYTFPYmdlUkJ nODJudnpMYnRQTklRIiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyI2VWhsZU5HUmJtc0 xDOFRndTh2OFdnIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~eyJhbGciOiAiRVMyNTYif Q.eyJub25jZSI6ICJYWk9VY28xdV9nRVBrbnhTNzhzV1dnIiwgImF1ZCI6ICJodHRwcz ovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgImlhdCI6IDE2Nzc4MzgwODR9.9yDey7Mo8 ZBljM31FKpzGROJwKZbsxPlNl1B8l4y820bDEOnUL7AhzZjGJFBaUrPkrWVtWP0FO4Fc B44Ma0LDg¶
The Holder MUST perform the following (or equivalent) steps when receiving a Combined Format for Issuance:¶
It is up to the Holder how to maintain the mapping between the Disclosures and the plaintext claim values to be able to display them to the End-User when needed.¶
For presentation to a Verifier, the Holder MUST perform the following (or equivalent) steps:¶
Upon receiving a Presentation, Verifiers MUST ensure that¶
To this end, Verifiers MUST follow the following steps (or equivalent):¶
Validate the SD-JWT:¶
none
algorithm MUST NOT be accepted.¶
nbf
, iat
, and exp
claims, if provided in the SD-JWT, and not selectively disclosed.¶
_sd_alg
claim is present and its value is understood and the hash algorithm is deemed secure.¶
Process the Disclosures. For each Disclosure provided:¶
Find all _sd
keys in the SD-JWT payload. For each such key:¶
Otherwise, process each digest in the _sd
array as follows:¶
_sd
key, a new claim using the claim name and claim value from the Disclosure.¶
_sd
key, recursively process the key as described before.¶
_sd
keys from the SD-JWT payload.¶
_sd_alg
from the SD-JWT payload.¶
If Holder Binding is required:¶
Otherwise, verify the Holder Binding JWT as follows:¶
none
algorithm MUST NOT be accepted.¶
nbf
, iat
, and exp
claims, if provided in the Holder Binding JWT.¶
nonce
and aud
field within the Holder Binding JWT.¶
If any step fails, the Presentation is not valid and processing MUST be aborted.¶
Otherwise, the processed SD-JWT payload can be passed to the application to be used for the intended purpose.¶
In some applications or transport protocols, it is desirable to put an SD-JWT and associated Disclosures into a JWT container. For example, an implementation may envelope all credentials and presentations, independent of their format, in a JWT to enable application-layer encryption during transport.¶
For such use cases, the SD-JWT and the respective Disclosures SHOULD be transported as a single string using the Combined Formats for Issuance and Presentation, respectively. Holder Binding MAY be achieved by signing the envelope JWT instead of adding a separate Holder Binding JWT as described in Section 5.4.1.¶
The claim _sd_jwt
SHOULD be used when transporting a Combined Format unless the application or protocol defines a different claim name.¶
The following non-normative example shows a Combined Format for Presentation enveloped in a JWT payload:¶
{ "iss": "https://holder.example.com", "sub": "did:example:123", "aud": "https://verifier.example.com", "exp": 1590000000, "iat": 1580000000, "nbf": 1580000000, "jti": "urn:uuid:12345678-1234-1234-1234-123456789012", "_sd_jwt": "eyJhbGci...emhlaUJhZzBZ~eyJhb...dYALCGg~" }¶
Here, eyJhbGci...emhlaUJhZzBZ
represents the SD-JWT and eyJhb...dYALCGg
represents a Disclosure. The Combined Format for Presentation does not contain a Holder Binding JWT as the outer container can be signed instead.¶
Other specifications or profiles of this specification may define alternative formats for transporting the Combined Format for Presentation that envelopes multiple such objects into one object, and provides Holder Binding using means other than Holder Binding JWT.¶
Security considerations in this section help achieve the following properties:¶
The SD-JWT MUST be signed by the Issuer to protect integrity of the issued claims. An attacker can modify or add claims if an SD-JWT is not signed (e.g., change the "email" attribute to take over the victim's account or add an attribute indicating a fake academic qualification).¶
The Verifier MUST always check the SD-JWT signature to ensure that the SD-JWT has not been tampered with since its issuance. If the signature on the SD-JWT cannot be verified, the SD-JWT MUST be rejected.¶
Holders can manipulate the Disclosures by changing the values of the claims before sending them to the Issuer. The Issuer MUST check the Disclosures to ensure that the values of the claims are correct, i.e., the digests of the Disclosures are actually present in the signed SD-JWT.¶
A naive Verifier that extracts all claim values from the Disclosures (without checking the hashes) and inserts them into the SD-JWT payload is vulnerable to this attack. However, in a structured SD-JWT, without comparing the digests of the Disclosures, such an implementation could not determine the correct place in a nested object where a claim needs to be inserted. Therefore, the naive implementation would not only be insecure, but also incorrect.¶
The steps described in Section 6.2 ensure that the Verifier checks the Disclosures correctly.¶
The security model that conceals the plaintext claims relies on the fact that salts not revealed to an attacker cannot be learned or guessed by the attacker, even if other salts have been revealed. It is vitally important to adhere to this principle. As such, each salt MUST be created in such a manner that it is cryptographically random, long enough, and has high entropy that it is not practical for the attacker to guess. A new salt MUST be chosen for each claim independently from other salts.¶
The RECOMMENDED minimum length of the randomly-generated portion of the salt is 128 bits.¶
The Issuer MUST ensure that a new salt value is chosen for each claim,
including when the same claim name occurs at different places in the
structure of the SD-JWT. This can be seen in Example 3 in the Appendix,
where multiple claims with the name type
appear, but each of them has
a different salt.¶
For the security of this scheme, the hash algorithm is required to be preimage resistant and second-preimage resistant, i.e., it is infeasible to calculate the salt and claim value that result in a particular digest, and, for any salt and claim value pair, it is infeasible to find a different salt and claim value pair that result in the same digest, respectively.¶
Hash algorithms that do not meet the aforementioned requirements MUST NOT be used.
Inclusion in the "Named Information Hash Algorithm" registry [IANA.Hash.Algorithms]
alone does not indicate a hash algorithm's suitability for use in SD-JWT (it contains several
heavily truncated digests, such as sha-256-32
and sha-256-64
, which are unfit for security
applications).¶
Furthermore, the hash algorithms MD2, MD4, MD5, RIPEMD-160, and SHA-1 revealed fundamental weaknesses and they MUST NOT be used.¶
Holder binding aims to ensure that the presenter of a credential is actually the legitimate Holder of the credential. There are, in general, two approaches to Holder Binding: Claims-based Holder Binding and Crpytographic Holder Binding.¶
Claims-based Holder Binding means that the Issuer includes claims in the SD-JWT that a Verifier can correlate with the Holder, potentially with the help of other credentials presented at the same time. For example, in a vaccination certificate, the Issuer can include a claim that contains the Holder's name and birthdate, and a Verifier can correlate this data with the Holder's passport that has to be presented together with the vaccination certificate - either as a digital credential or a physical document.¶
Cryptographic Holder Binding means that the Issuer includes some cryptographic data, usually a public key, belonging to the Holder. The Holder can then sign over some data defined by the Verifier to prove that the Holder is in possession of the private key.¶
Without Holder Binding, a Verifier only gets the proof that the credential was issued by a particular Issuer, but the credential itself can be replayed by anyone who gets access to it. This means that, for example, after a credential was leaked to an attacker, the attacker can present the credential to any verifier that does not require Holder Binding. But also a malicious Verifier to which the Holder presented the credential can present the credential to another Verifier if that other Verifier does not require Holder Binding.¶
Verifiers MUST decide whether Holder Binding is required for a particular use case or not before verifying a credential. This decision can be informed by various factors including, but not limited to the following: business requirements, the use case, the type of binding between a Holder and its credential that is required for a use case, the sensitivity of the use case, the expected properties of a credential, the type and contents of other credentials expected to be presented at the same time, etc.¶
This can be showcased based on two scenarios for a mobile driver's license use case for SD-JWT:¶
Scenario A: For the verification of the driver's license when stopped by a police officer for exceeding a speed limit, Holder Binding may be necessary to ensure that the person driving the car and presenting the license is the actual Holder of the license. The Verifier (e.g., the software used by the police officer) will ensure that a Holder Binding JWT is present and signed with the Holder's private key. Claims-based Holder Binding may be used as well, e.g., by including a first name, last name and a date of birth that matches that of an insurance policy paper.¶
Scenario B: A rental car agency may want to ensure, for insurance purposes, that all drivers named on the rental contract own a government-issued driver's license. The signer of the rental contract can present the mobile driver's license of all named drivers. In this case, the rental car agency does not need to check Holder Binding as the goal is not to verify the identity of the person presenting the license, but to verify that a license exists and is valid.¶
It is important that a Verifier does not make its security policy decisions based on data that can be influenced by an attacker or that can be misinterpreted. For this reason, when deciding whether Holder binding is required or not, Verifiers MUST NOT take into account¶
If a Verifier has decided that Holder Binding is required for a particular use case and the Holder Binding is not present, does not fulfill the requirements (e.g., on the signing algorithm), or no recognized Holder Binding data is present in the SD-JWT, the Verifier will reject the presentation, as described in Section 6.2.¶
SD-JWT ensures that names of claims that are selectively disclosable are always blinded. This prevents an attacker from learning the names of the disclosable claims. However, the names of the claims that are not disclosable are not blinded. This includes the keys of objects that themselves are not blinded, but contain disclosable claims. This limitation needs to be taken into account by Issuers when creating the structure of the SD-JWT.¶
This specification does not define how signature verification keys of Issuers are distributed to Verifiers. However, it is RECOMMENDED that Issuers publish their keys in a way that allows for efficient and secure key rotation and revocation, for example, by publishing keys at a predefined location using the JSON Web Key Set (JWKS) format [RFC7517]. Verifiers need to ensure that they are not using expired or revoked keys for signature verification using reasonable and appropriate means for the given key-distribution method.¶
The privacy principles of [ISO.29100] should be adhered to.¶
Wherever End-User data is stored, it represents a potential target for an attacker. This target can be of particularly high value when the data is signed by a trusted authority like an official national identity service. For example, in OpenID Connect, signed ID Tokens can be stored by Relying Parties. In the case of SD-JWT, Holders have to store signed SD-JWTs and associated Disclosures, and Issuers and Verifiers may decide to do so as well.¶
Not surprisingly, a leak of such data risks revealing private data of End-Users to third parties. Signed End-User data, the authenticity of which can be easily verified by third parties, further exacerbates the risk. As discussed in Section 8.6, leaked SD-JWTs may also allow attackers to impersonate Holders unless Holder Binding is enforced and the attacker does not have access to the Holder's cryptographic keys. Altogether, leaked SD-JWT credentials may have a high monetary value on black markets.¶
Due to these risks, systems implementing SD-JWT SHOULD be designed to minimize the amount of data that is stored. All involved parties SHOULD store SD-JWTs only for as long as needed, including in log files.¶
Issuers SHOULD NOT store SD-JWTs after issuance.¶
Holders SHOULD store SD-JWTs and associated Disclosures only in encrypted form, and, wherever possible, use hardware-backed encryption in particular for the private Holder Binding key. Decentralized storage of data, e.g., on End-User devices, SHOULD be preferred for End-User credentials over centralized storage. Expired SD-JWTs SHOULD be deleted as soon as possible.¶
Verifiers SHOULD NOT store SD-JWTs after verification. It may be sufficient to store the result of the verification and any End-User data that is needed for the application.¶
If reliable and secure key rotation and revocation is ensured according to Section 8.8, Issuers may opt to publish expired or revoked private signing keys (after a grace period that ensures that the keys are not cached any longer at any Verifier). This reduces the value of any leaked credentials as the signatures on them can no longer be trusted to originate from the Issuer.¶
If the SD-JWT and associated Disclosures are transmitted over an insecure channel during issuance or presentation, an adversary may be able to intercept and read the End-User's personal data or correlate the information with previous uses of the same SD-JWT.¶
Usually, transport protocols for issuance and presentation of credentials are designed to protect the confidentiality of the transmitted data, for example, by requiring the use of TLS.¶
This specification therefore considers the confidentiality of the data to be provided by the transport protocol and does not specify any encryption mechanism.¶
Implementers MUST ensure that the transport protocol provides confidentiality if the privacy of End-User data or correlation attacks by passive observers are a concern. Implementers MAY define an envelope format (such as described in Section 7 or nesting the SD-JWT Combined Format as the plaintext payload of a JWE) to encrypt the SD-JWT and associated Disclosures when transmitted over an insecure channel.¶
The use of decoy digests is RECOMMENDED when the number of claims (or the existence of particular claims) can be a side-channel disclosing information about otherwise undisclosed claims. In particular, if a claim in an SD-JWT is present only if a certain condition is met (e.g., a membership number is only contained if the End-User is a member of a group), the Issuer SHOULD add decoy digests when the condition is not met.¶
Decoy digests increase the size of the SD-JWT. The number of decoy digests (or whether to use them at all) is a trade-off between the size of the SD-JWT and the privacy of the End-User's data.¶
Colluding Issuer/Verifier or Verifier/Verifier pairs could link issuance/presentation or two presentation sessions to the same user on the basis of unique values encoded in the SD-JWT (Issuer signature, salts, digests, etc.).¶
To prevent these types of linkability, various methods, including but not limited to the following ones can be used:¶
An Issuer issuing only one type of SD-JWT might have privacy implications, because if the Holder has an SD-JWT issued by that Issuer, its type and claim names can be determined.¶
For example, if the National Cancer Institute only issued SD-JWTs with cancer registry information, it is possible to deduce that the Holder owning its SD-JWT is a cancer patient.¶
Moreover, the issuer identifier alone may reveal information about the user.¶
For example, when a military organization or a drug rehabilitation center issues a vaccine credential, verifiers can deduce that the holder is a military member or may have a substance use disorder.¶
To mitigate this issue, a group of issuers may elect to use a common Issuer identifier. A group signature scheme outside the scope of this specification may also be used, instead of an individual signature.¶
We would like to thank Alen Horvat, Arjan Geluk, Christian Paquin, David Bakker, David Waite, Fabian Hauck, Giuseppe De Marco, John Mattsson, Matthew Miller, Justin Richer, Kushal Das, Mike Jones, Nat Sakimura, Orie Steele, Pieter Kasselman, Ryosuke Abe, Shawn Butterfield, Torsten Lodderstedt, and Vittorio Bertocci for their contributions (some of which substantial) to this draft and to the initial set of implementations.¶
The work on this draft was started at OAuth Security Workshop 2022 in Trondheim, Norway.¶
TBD¶
@VC_JWT¶
All of the following examples are non-normative.¶
This example uses the following object as the set of claims that the Issuer is issuing:¶
{ "sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c", "given_name": "太郎", "family_name": "山田", "email": "\"unusual email address\"@example.jp", "phone_number": "+81-80-1234-5678", "address": { "street_address": "東京都港区芝公園4丁目2−8", "locality": "東京都", "region": "港区", "country": "JP" }, "birthdate": "1940-01-01" }¶
Note that in contrast to Example 1, here the Issuer decided to create a structured object for the address
claim, allowing for separate disclosure of the individual members of the claim.¶
{ "_sd": [ "-rAXuBrq1MIGJnPr_vGdgVhinHfvtw6HMvkMQ6rk1Po", "ZRtxg42klTl-Ap_OiwNVh49ZCGM059AmHPayFqbMilE", "g_WrTVyjFFsppeKOjcgAK8nLTeY8IcPAYSz00xNn5Rk", "hblncirSgqjt8gTQ56jy7FUd1cpCg0orxca0C-o9aoo", "lagH02GaboFAO6_d2R8jpdjO-Xxnh4aVAG9cE8iV4Sg", "p3vzUx7kYcA_dOlOQpyf8Z8J4s1ZPfhXWZNFuI4JgvU", "s2OMJlfL0E9i46-mM3sQKxJ0bEs3bNwBrzXhObM7iR0" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "_sd_alg": "sha-256" }¶
The Disclosures for this SD-JWT are as follows:¶
Disclosure for sub
:¶
SHA-256 Hash: hblncirSgqjt8gTQ56jy7FUd1cpCg0orxca0C-o9aoo
¶
Disclosure:¶
WyIzWFQxYV8tOFBRNFlweEZnczRiUG9RIiwgInN1YiIsICI2YzVjMGE0OS1iNTg5LTQz MWQtYmFlNy0yMTkxMjJhOWVjMmMiXQ¶
Contents:¶
["3XT1a_-8PQ4YpxFgs4bPoQ", "sub", "6c5c0a49-b589-431d-bae7-219122a9ec2c"]¶
Disclosure for given_name
:¶
SHA-256 Hash: lagH02GaboFAO6_d2R8jpdjO-Xxnh4aVAG9cE8iV4Sg
¶
Disclosure:¶
WyJ3M3RSbkptLTZ4YXhtMHdWVFMxYV9nIiwgImdpdmVuX25hbWUiLCAiXHU1OTJhXHU5 MGNlIl0¶
Contents:¶
["w3tRnJm-6xaxm0wVTS1a_g", "given_name", "\u592a\u90ce"]¶
Disclosure for family_name
:¶
SHA-256 Hash: -rAXuBrq1MIGJnPr_vGdgVhinHfvtw6HMvkMQ6rk1Po
¶
Disclosure:¶
WyJGM3MxUENGOUt3eklEaUtKajZrekpRIiwgImZhbWlseV9uYW1lIiwgIlx1NWM3MVx1 NzUzMCJd¶
Contents:¶
["F3s1PCF9KwzIDiKJj6kzJQ", "family_name", "\u5c71\u7530"]¶
Disclosure for email
:¶
SHA-256 Hash: p3vzUx7kYcA_dOlOQpyf8Z8J4s1ZPfhXWZNFuI4JgvU
¶
Disclosure:¶
WyJpQl9adWNHQ3dmampRald5MEV0RVlnIiwgImVtYWlsIiwgIlwidW51c3VhbCBlbWFp bCBhZGRyZXNzXCJAZXhhbXBsZS5qcCJd¶
Contents:¶
["iB_ZucGCwfjjQjWy0EtEYg", "email", "\"unusual email address\"@example.jp"]¶
Disclosure for phone_number
:¶
SHA-256 Hash: ZRtxg42klTl-Ap_OiwNVh49ZCGM059AmHPayFqbMilE
¶
Disclosure:¶
WyJMR3hTaXJELTdsRHB6SWlsVHpYdXdnIiwgInBob25lX251bWJlciIsICIrODEtODAt MTIzNC01Njc4Il0¶
Contents:¶
["LGxSirD-7lDpzIilTzXuwg", "phone_number", "+81-80-1234-5678"]¶
Disclosure for address
:¶
SHA-256 Hash: s2OMJlfL0E9i46-mM3sQKxJ0bEs3bNwBrzXhObM7iR0
¶
Disclosure:¶
WyJlT1hQUDJNYTAzNTNiai1qLTVPRGFnIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRy ZXNzIjogIlx1Njc3MVx1NGVhY1x1OTBmZFx1NmUyZlx1NTMzYVx1ODI5ZFx1NTE2Y1x1 NTcxMlx1ZmYxNFx1NGUwMVx1NzZlZVx1ZmYxMlx1MjIxMlx1ZmYxOCIsICJsb2NhbGl0 eSI6ICJcdTY3NzFcdTRlYWNcdTkwZmQiLCAicmVnaW9uIjogIlx1NmUyZlx1NTMzYSIs ICJjb3VudHJ5IjogIkpQIn1d¶
Contents:¶
["eOXPP2Ma0353bj-j-5ODag", "address", {"street_address": "\u6771\u4e ac\u90fd\u6e2f\u533a\u829d\u516c\u5712\uff14\u4e01\u76ee\uff12\u2212 \uff18", "locality": "\u6771\u4eac\u90fd", "region": "\u6e2f\u533a", "country": "JP"}]¶
Disclosure for birthdate
:¶
SHA-256 Hash: g_WrTVyjFFsppeKOjcgAK8nLTeY8IcPAYSz00xNn5Rk
¶
Disclosure:¶
WyJwN3dJOHpfenlzQUN4ODVYOTgtWmFRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAx Il0¶
Contents:¶
["p7wI8z_zysACx85X98-ZaQ", "birthdate", "1940-01-01"]¶
A Presentation for the SD-JWT that discloses only region
and country
of the address
property and without a Holder Binding JWT could look as follows:¶
eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIi1yQVh1QnJxMU1JR0puUHJfdkdkZ1Zoa W5IZnZ0dzZITXZrTVE2cmsxUG8iLCAiWlJ0eGc0MmtsVGwtQXBfT2l3TlZoNDlaQ0dNM DU5QW1IUGF5RnFiTWlsRSIsICJnX1dyVFZ5akZGc3BwZUtPamNnQUs4bkxUZVk4SWNQQ VlTejAweE5uNVJrIiwgImhibG5jaXJTZ3FqdDhnVFE1Nmp5N0ZVZDFjcENnMG9yeGNhM EMtbzlhb28iLCAibGFnSDAyR2Fib0ZBTzZfZDJSOGpwZGpPLVh4bmg0YVZBRzljRThpV jRTZyIsICJwM3Z6VXg3a1ljQV9kT2xPUXB5ZjhaOEo0czFaUGZoWFdaTkZ1STRKZ3ZVI iwgInMyT01KbGZMMEU5aTQ2LW1NM3NRS3hKMGJFczNiTndCcnpYaE9iTTdpUjAiXSwgI mlzcyI6ICJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsICJpYXQiOiAxNTE2MjM5M DIyLCAiZXhwIjogMTczNTY4OTY2MSwgIl9zZF9hbGciOiAic2hhLTI1NiJ9.RSSv9c9Q ph0QhSNonj_biqZr1koH1WbNBw_FQMD4-taS8oqieeUr5i_rugbdkvANo2q92HtvzJ8S KfOpLBi2Vw~WyJGM3MxUENGOUt3eklEaUtKajZrekpRIiwgImZhbWlseV9uYW1lIiwgI lx1NWM3MVx1NzUzMCJd~WyJwN3dJOHpfenlzQUN4ODVYOTgtWmFRIiwgImJpcnRoZGF0 ZSIsICIxOTQwLTAxLTAxIl0~WyJ3M3RSbkptLTZ4YXhtMHdWVFMxYV9nIiwgImdpdmVu X25hbWUiLCAiXHU1OTJhXHU5MGNlIl0~WyJpQl9adWNHQ3dmampRald5MEV0RVlnIiwg ImVtYWlsIiwgIlwidW51c3VhbCBlbWFpbCBhZGRyZXNzXCJAZXhhbXBsZS5qcCJd~WyJ lT1hQUDJNYTAzNTNiai1qLTVPRGFnIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXN zIjogIlx1Njc3MVx1NGVhY1x1OTBmZFx1NmUyZlx1NTMzYVx1ODI5ZFx1NTE2Y1x1NTc xMlx1ZmYxNFx1NGUwMVx1NzZlZVx1ZmYxMlx1MjIxMlx1ZmYxOCIsICJsb2NhbGl0eSI 6ICJcdTY3NzFcdTRlYWNcdTkwZmQiLCAicmVnaW9uIjogIlx1NmUyZlx1NTMzYSIsICJ jb3VudHJ5IjogIkpQIn1d~¶
This example is based on the same set of user data as Example 2a, but here, the Issuer decided to add decoy digests to the SD-JWT.¶
The SD-JWT payload is as follows:¶
{ "_sd": [ "Bjq8C3IYd_T7sPnFaLW0rFxcGS38tFaF4N04yxPapPM", "CumxYvjP8bktgbI_AE6JNVCqAMu-WIqgl-uiXb0MdVU", "E02ULAmabgHhofkyV8ity0bGQxknP_OwHuYk9pO91a8", "Gb99XLWQ8dw3a6Mb6pbbzojv-JUr9mLifcPekGqfoN8", "kEII5g1ez1VcLVApcjmUmZnYG2VRA8IxFBi0Q0FhLzc", "x2i1zOePQ8VpoceJa_-Ln89TD7d-Px4BAY4G9sjELNk", "z2WPjyH1cG3pwqhHVm89iX3gW82VmOV_0VlzMb0c0oQ", "zA3zOqIDbohbtOInLFK9Qju1mbndVtawOdZkCyUoxmg", "zPd_yrC5okdqofSD68hXpdR5UNkPr5N71UVaE-jcUYM" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "_sd_alg": "sha-256" }¶
Since the Disclosures or Presentation are not affected by the decoy digests (other than a slightly larger SD-JWT), they are omitted here.¶
In this example, an SD-JWT with a complex object is demonstrated. Here, the data structures defined in OIDC4IDA [OIDC.IDA] are used.¶
The Issuer is using the following user data:¶
{ "verified_claims": { "verification": { "trust_framework": "de_aml", "time": "2012-04-23T18:25Z", "verification_process": "f24c6f-6d3f-4ec5-973e-b0d8506f3bc7", "evidence": [ { "type": "document", "method": "pipp", "time": "2012-04-22T11:30Z", "document": { "type": "idcard", "issuer": { "name": "Stadt Augsburg", "country": "DE" }, "number": "53554554", "date_of_issuance": "2010-03-23", "date_of_expiry": "2020-03-22" } } ] }, "claims": { "given_name": "Max", "family_name": "Müller", "nationalities": [ "DE" ], "birthdate": "1956-01-28", "place_of_birth": { "country": "IS", "locality": "Þykkvabæjarklaustur" }, "address": { "locality": "Maxstadt", "postal_code": "12344", "country": "DE", "street_address": "Weidenstraße 22" } } }, "birth_middle_name": "Timotheus", "salutation": "Dr.", "msisdn": "49123456789" }¶
The Issuer in this example sends the two claims birthdate
and place_of_birth
in the claims
element in plain text. The following shows the resulting SD-JWT payload:¶
{ "_sd": [ "BjJ85b1mpIvorC35da8cPRCfN0OeoBUf7ZCA3w96xnM", "XqnTomboGac-QASg2Q9V1uQGRQRkXL9jkveIzNcMmSM", "wN-gqrZTxUtl1-v3S5wodjuAgE0YuBS66s9p4qxfgxg" ], "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "verified_claims": { "verification": { "_sd": [ "OSXqQur4cQzXkSlbTehtzOzsZBMgAIigvZmiNCV5Vd8", "pnJqIq45n58u7BY1Z0nZYvL1nqucjI7mo_voHoq9oGU" ], "trust_framework": "de_aml", "evidence": [ { "_sd": [ "FPNPZmj_KaKlIP2QWB55J1gHhA14mPlbVdR9bGBgH4w", "Vytbjbb4wHiTvFi9WxsqJYqPPsW_nnvWvtp0U-Kuof8", "evYB510b8xzp19Q7Gn1i2EgyN0-R26oFjeBB5IDTGYI", "oOBXkmNPDoEJsh5K5hgc3wdMbJJzc9Rv0hOn0mU6Ym8" ] } ] }, "claims": { "_sd": [ "OTog0pBGyAmwEqIhjSuf5Rq5UWTkIecAnutwB2nGUlk", "U4P6UrikZAVE3mk82oLaPDiLX8hEXmEu9A6xO5j9mxE", "Ylx9AxQmJxSR9CgZmFBnyKCha9qNsnA7GzrmXPBKkDo", "d7ln7xO-RREXmecBVEpwLwrEjZ3FKs_KLhCD0vL74Us", "fIW6zXRtRSQNcNK5gvpRsZFkaN8BMh36UwhsdZlxoTo", "fSw3UyxwNFf_CjYCCBYCRxZCGB-LIS35Pey2T7G_cHw" ] } }, "_sd_alg": "sha-256" }¶
With the following Disclosures:¶
Disclosure for time
:¶
SHA-256 Hash: OSXqQur4cQzXkSlbTehtzOzsZBMgAIigvZmiNCV5Vd8
¶
Disclosure:¶
WyJjZllESjNFR2JFTFMyYkhsTWlrQ3FBIiwgInRpbWUiLCAiMjAxMi0wNC0yM1QxODoy NVoiXQ¶
Contents:¶
["cfYDJ3EGbELS2bHlMikCqA", "time", "2012-04-23T18:25Z"]¶
Disclosure for verification_process
:¶
SHA-256 Hash: pnJqIq45n58u7BY1Z0nZYvL1nqucjI7mo_voHoq9oGU
¶
Disclosure:¶
WyJRWXFYWjdwdmdya3I3MjFNbkV5dVJnIiwgInZlcmlmaWNhdGlvbl9wcm9jZXNzIiwg ImYyNGM2Zi02ZDNmLTRlYzUtOTczZS1iMGQ4NTA2ZjNiYzciXQ¶
Contents:¶
["QYqXZ7pvgrkr721MnEyuRg", "verification_process", "f24c6f-6d3f-4ec5-973e-b0d8506f3bc7"]¶
Disclosure for type
:¶
SHA-256 Hash: oOBXkmNPDoEJsh5K5hgc3wdMbJJzc9Rv0hOn0mU6Ym8
¶
Disclosure:¶
WyJrZ2l1OHFOM1ppZ3kxZ3RGQ1owNlR3IiwgInR5cGUiLCAiZG9jdW1lbnQiXQ¶
Contents:¶
["kgiu8qN3Zigy1gtFCZ06Tw", "type", "document"]¶
Disclosure for method
:¶
SHA-256 Hash: evYB510b8xzp19Q7Gn1i2EgyN0-R26oFjeBB5IDTGYI
¶
Disclosure:¶
WyJrMm53eWt1eGdhdERDVllxTVg3WXVRIiwgIm1ldGhvZCIsICJwaXBwIl0¶
Contents:¶
["k2nwykuxgatDCVYqMX7YuQ", "method", "pipp"]¶
Disclosure for time
:¶
SHA-256 Hash: Vytbjbb4wHiTvFi9WxsqJYqPPsW_nnvWvtp0U-Kuof8
¶
Disclosure:¶
WyJFd2VBVWt3THJnVVpJaGZZbEgwY29RIiwgInRpbWUiLCAiMjAxMi0wNC0yMlQxMToz MFoiXQ¶
Contents:¶
["EweAUkwLrgUZIhfYlH0coQ", "time", "2012-04-22T11:30Z"]¶
Disclosure for document
:¶
SHA-256 Hash: FPNPZmj_KaKlIP2QWB55J1gHhA14mPlbVdR9bGBgH4w
¶
Disclosure:¶
WyJXVDhPVC05RnJwbTk5WEpQa1UtWTdRIiwgImRvY3VtZW50IiwgeyJ0eXBlIjogImlk Y2FyZCIsICJpc3N1ZXIiOiB7Im5hbWUiOiAiU3RhZHQgQXVnc2J1cmciLCAiY291bnRy eSI6ICJERSJ9LCAibnVtYmVyIjogIjUzNTU0NTU0IiwgImRhdGVfb2ZfaXNzdWFuY2Ui OiAiMjAxMC0wMy0yMyIsICJkYXRlX29mX2V4cGlyeSI6ICIyMDIwLTAzLTIyIn1d¶
Contents:¶
["WT8OT-9Frpm99XJPkU-Y7Q", "document", {"type": "idcard", "issuer": {"name": "Stadt Augsburg", "country": "DE"}, "number": "53554554", "date_of_issuance": "2010-03-23", "date_of_expiry": "2020-03-22"}]¶
Disclosure for given_name
:¶
SHA-256 Hash: Ylx9AxQmJxSR9CgZmFBnyKCha9qNsnA7GzrmXPBKkDo
¶
Disclosure:¶
WyJuVWtieGhxc2pyVTNaTEtVSGNBYWxBIiwgImdpdmVuX25hbWUiLCAiTWF4Il0¶
Contents:¶
["nUkbxhqsjrU3ZLKUHcAalA", "given_name", "Max"]¶
Disclosure for family_name
:¶
SHA-256 Hash: fIW6zXRtRSQNcNK5gvpRsZFkaN8BMh36UwhsdZlxoTo
¶
Disclosure:¶
WyIyTmd0UExxQmU0QVhMVzR6SUNLWHJ3IiwgImZhbWlseV9uYW1lIiwgIk1cdTAwZmNs bGVyIl0¶
Contents:¶
["2NgtPLqBe4AXLW4zICKXrw", "family_name", "M\u00fcller"]¶
Disclosure for nationalities
:¶
SHA-256 Hash: d7ln7xO-RREXmecBVEpwLwrEjZ3FKs_KLhCD0vL74Us
¶
Disclosure:¶
WyJQUy1fNnFqdFk0akpOSlF5SkNpeU5BIiwgIm5hdGlvbmFsaXRpZXMiLCBbIkRFIl1d¶
Contents:¶
["PS-_6qjtY4jJNJQyJCiyNA", "nationalities", ["DE"]]¶
Disclosure for birthdate
:¶
SHA-256 Hash: U4P6UrikZAVE3mk82oLaPDiLX8hEXmEu9A6xO5j9mxE
¶
Disclosure:¶
WyJMNExJMTRqVGFCVEZxV080MVM5TUlRIiwgImJpcnRoZGF0ZSIsICIxOTU2LTAxLTI4 Il0¶
Contents:¶
["L4LI14jTaBTFqWO41S9MIQ", "birthdate", "1956-01-28"]¶
Disclosure for place_of_birth
:¶
SHA-256 Hash: fSw3UyxwNFf_CjYCCBYCRxZCGB-LIS35Pey2T7G_cHw
¶
Disclosure:¶
WyJsZ1pCenNHUUZ6bGlqRFZKa2ZCVGNRIiwgInBsYWNlX29mX2JpcnRoIiwgeyJjb3Vu dHJ5IjogIklTIiwgImxvY2FsaXR5IjogIlx1MDBkZXlra3ZhYlx1MDBlNmphcmtsYXVz dHVyIn1d¶
Contents:¶
["lgZBzsGQFzlijDVJkfBTcQ", "place_of_birth", {"country": "IS", "locality": "\u00deykkvab\u00e6jarklaustur"}]¶
Disclosure for address
:¶
SHA-256 Hash: OTog0pBGyAmwEqIhjSuf5Rq5UWTkIecAnutwB2nGUlk
¶
Disclosure:¶
WyI5VEFiRnplajZoNGFDSVc2dTZoWFZBIiwgImFkZHJlc3MiLCB7ImxvY2FsaXR5Ijog Ik1heHN0YWR0IiwgInBvc3RhbF9jb2RlIjogIjEyMzQ0IiwgImNvdW50cnkiOiAiREUi LCAic3RyZWV0X2FkZHJlc3MiOiAiV2VpZGVuc3RyYVx1MDBkZmUgMjIifV0¶
Contents:¶
["9TAbFzej6h4aCIW6u6hXVA", "address", {"locality": "Maxstadt", "postal_code": "12344", "country": "DE", "street_address": "Weidenstra\u00dfe 22"}]¶
Disclosure for birth_middle_name
:¶
SHA-256 Hash: BjJ85b1mpIvorC35da8cPRCfN0OeoBUf7ZCA3w96xnM
¶
Disclosure:¶
WyJZdVhXUzI3N3ZIX3RuRWZhWWw5S1R3IiwgImJpcnRoX21pZGRsZV9uYW1lIiwgIlRp bW90aGV1cyJd¶
Contents:¶
["YuXWS277vH_tnEfaYl9KTw", "birth_middle_name", "Timotheus"]¶
Disclosure for salutation
:¶
SHA-256 Hash: wN-gqrZTxUtl1-v3S5wodjuAgE0YuBS66s9p4qxfgxg
¶
Disclosure:¶
WyJPWEVMTkhsQ2NNS051cHN0T1F1N19RIiwgInNhbHV0YXRpb24iLCAiRHIuIl0¶
Contents:¶
["OXELNHlCcMKNupstOQu7_Q", "salutation", "Dr."]¶
Disclosure for msisdn
:¶
SHA-256 Hash: XqnTomboGac-QASg2Q9V1uQGRQRkXL9jkveIzNcMmSM
¶
Disclosure:¶
WyI2QzFBbVhiUjc5aG1zcWJfYkhfWHdBIiwgIm1zaXNkbiIsICI0OTEyMzQ1Njc4OSJd¶
Contents:¶
["6C1AmXbR79hmsqb_bH_XwA", "msisdn", "49123456789"]¶
The Verifier would receive the Issuer-signed SD-JWT together with a selection of the Disclosures. The Presentation in this example would look as follows:¶
eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIkJqSjg1YjFtcEl2b3JDMzVkYThjUFJDZ k4wT2VvQlVmN1pDQTN3OTZ4bk0iLCAiWHFuVG9tYm9HYWMtUUFTZzJROVYxdVFHUlFSa 1hMOWprdmVJek5jTW1TTSIsICJ3Ti1ncXJaVHhVdGwxLXYzUzV3b2RqdUFnRTBZdUJTN jZzOXA0cXhmZ3hnIl0sICJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1ZXIiL CAiaWF0IjogMTUxNjIzOTAyMiwgImV4cCI6IDE3MzU2ODk2NjEsICJ2ZXJpZmllZF9jb GFpbXMiOiB7InZlcmlmaWNhdGlvbiI6IHsiX3NkIjogWyJPU1hxUXVyNGNRelhrU2xiV GVodHpPenNaQk1nQUlpZ3ZabWlOQ1Y1VmQ4IiwgInBuSnFJcTQ1bjU4dTdCWTFaMG5aW XZMMW5xdWNqSTdtb192b0hvcTlvR1UiXSwgInRydXN0X2ZyYW1ld29yayI6ICJkZV9hb WwiLCAiZXZpZGVuY2UiOiBbeyJfc2QiOiBbIkZQTlBabWpfS2FLbElQMlFXQjU1SjFnS GhBMTRtUGxiVmRSOWJHQmdINHciLCAiVnl0YmpiYjR3SGlUdkZpOVd4c3FKWXFQUHNXX 25udld2dHAwVS1LdW9mOCIsICJldllCNTEwYjh4enAxOVE3R24xaTJFZ3lOMC1SMjZvR mplQkI1SURUR1lJIiwgIm9PQlhrbU5QRG9FSnNoNUs1aGdjM3dkTWJKSnpjOVJ2MGhPb jBtVTZZbTgiXX1dfSwgImNsYWltcyI6IHsiX3NkIjogWyJPVG9nMHBCR3lBbXdFcUloa lN1ZjVScTVVV1RrSWVjQW51dHdCMm5HVWxrIiwgIlU0UDZVcmlrWkFWRTNtazgyb0xhU ERpTFg4aEVYbUV1OUE2eE81ajlteEUiLCAiWWx4OUF4UW1KeFNSOUNnWm1GQm55S0NoY TlxTnNuQTdHenJtWFBCS2tEbyIsICJkN2xuN3hPLVJSRVhtZWNCVkVwd0x3ckVqWjNGS 3NfS0xoQ0Qwdkw3NFVzIiwgImZJVzZ6WFJ0UlNRTmNOSzVndnBSc1pGa2FOOEJNaDM2V Xdoc2RabHhvVG8iLCAiZlN3M1V5eHdORmZfQ2pZQ0NCWUNSeFpDR0ItTElTMzVQZXkyV DdHX2NIdyJdfX0sICJfc2RfYWxnIjogInNoYS0yNTYifQ.gRq0kmKG8b3e6fW74FMEc6 0D0z9EfblAYHXoMQLUXyLACQabr3WjEnzP_-Us-KvclwMy9MmuPi_rT6LINMAwcg~WyJ jZllESjNFR2JFTFMyYkhsTWlrQ3FBIiwgInRpbWUiLCAiMjAxMi0wNC0yM1QxODoyNVo iXQ~WyJrMm53eWt1eGdhdERDVllxTVg3WXVRIiwgIm1ldGhvZCIsICJwaXBwIl0~WyI5 VEFiRnplajZoNGFDSVc2dTZoWFZBIiwgImFkZHJlc3MiLCB7ImxvY2FsaXR5IjogIk1h eHN0YWR0IiwgInBvc3RhbF9jb2RlIjogIjEyMzQ0IiwgImNvdW50cnkiOiAiREUiLCAi c3RyZWV0X2FkZHJlc3MiOiAiV2VpZGVuc3RyYVx1MDBkZmUgMjIifV0~WyJuVWtieGhx c2pyVTNaTEtVSGNBYWxBIiwgImdpdmVuX25hbWUiLCAiTWF4Il0~WyIyTmd0UExxQmU0 QVhMVzR6SUNLWHJ3IiwgImZhbWlseV9uYW1lIiwgIk1cdTAwZmNsbGVyIl0~¶
After the verification of the data, the Verifier will pass the following result on to the application for further processing:¶
{ "iss": "https://example.com/issuer", "iat": 1516239022, "exp": 1735689661, "verified_claims": { "verification": { "trust_framework": "de_aml", "evidence": [ { "method": "pipp" } ], "time": "2012-04-23T18:25Z" }, "claims": { "address": { "locality": "Maxstadt", "postal_code": "12344", "country": "DE", "street_address": "Weidenstraße 22" }, "given_name": "Max", "family_name": "Müller" } }, "_sd_alg": "sha-256" }¶
This example illustrates how to use the artifacts defined in this specification to secure a payload
that is represented as a W3C Verifiable Credentials Data Model v2.0 [VC_DATA_v2.0]
and does not use JSON-LD to provide semantic definitions for claims. The example uses a content type credential-claims-set+json
defined in [VC_JWT], Section 3 in a cty
JOSE Header value.¶
SD-JWT is equivalent to an Issuer-signed W3C Verifiable Credential (W3C VC). Disclosures are sent alongside a W3C VC.¶
A Holder-signed Verifiable Presentation as defined in [VC_DATA_v2.0] is equivalent to a Combined Format for Presentation with a Holder Binding JWT.¶
In this example, Holder Binding is applied and Verifiable Presentation can be signed using
a Holder's public key passed in a cnf
Claim in the SD-JWT.¶
Below is a non-normative example of an SD-JWT represented as a W3C VC without using JSON-LD.¶
The following data will be used in this example:¶
{ "iss": "https://example.com", "jti": "http://example.com/credentials/3732", "nbf": 1541493724, "iat": 1541493724, "cnf": { "jwk": { "kty": "RSA", "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbf AAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMst n64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_F DW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9 1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHa Q-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e": "AQAB" } }, "type": "IdentityCredential", "credentialSubject": { "given_name": "John", "family_name": "Doe", "email": "johndoe@example.com", "phone_number": "+1-202-555-0101", "address": { "street_address": "123 Main St", "locality": "Anytown", "region": "Anystate", "country": "US" }, "birthdate": "1940-01-01", "is_over_18": true, "is_over_21": true, "is_over_65": true } }¶
The payload of a corresponding SD-JWT looks as follows:¶
{ "iss": "https://example.com", "iat": 1541493724, "exp": 1735689661, "jti": "http://example.com/credentials/3732", "nbf": 1541493724, "cnf": { "jwk": { "kty": "RSA", "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbf AAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMst n64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_F DW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9 1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHa Q-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e": "AQAB" } }, "type": "IdentityCredential", "credentialSubject": { "_sd": [ "2cj0qo1YI8aGLOPCEzIr0mexil6_9tVz5KnIpY3fszs", "H033gGqGyBCT7VmtYky-1gqqTg9JT8kg9WFJTTN1iVY", "RKE58nhM1GLxUmfvPaZhxNEq8kNplQYnOZlLJosLomY", "S7ebWHiOEgQDLG6JcpYkuMKMCb40uxFUSUimK94MuDc", "WkP5oQu7qxPAxLVPKcFuP4rD5TC0T4CekiYi333zQP4", "f4nimkh9dcwJ8JK46zlad_zgyYJfZFPImAWBNh86Kb0", "goqT4HD2DOmnPF1wNMLNiYuj4SgYtKjfQQHO--CSh0o", "lheBqvJLJPRLsoXVF68rmkn9jL73iGCF0V5sJjPlt68", "tAQ3Er6qd3UwQLrZYRe3fMF4J6MXdz5tJMJfJw48I0g" ] }, "_sd_alg": "sha-256" }¶
Disclosures:¶
Disclosure for given_name
:¶
SHA-256 Hash: f4nimkh9dcwJ8JK46zlad_zgyYJfZFPImAWBNh86Kb0
¶
Disclosure:¶
WyJuWUpCd1Q0OERQTEtYcVd1UmJ4NVNRIiwgImdpdmVuX25hbWUiLCAiSm9obiJd¶
Contents:¶
["nYJBwT48DPLKXqWuRbx5SQ", "given_name", "John"]¶
Disclosure for family_name
:¶
SHA-256 Hash: 2cj0qo1YI8aGLOPCEzIr0mexil6_9tVz5KnIpY3fszs
¶
Disclosure:¶
WyJFTXMzQjJ1LU5jUDdMeUljVnA5elhBIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd¶
Contents:¶
["EMs3B2u-NcP7LyIcVp9zXA", "family_name", "Doe"]¶
Disclosure for email
:¶
SHA-256 Hash: H033gGqGyBCT7VmtYky-1gqqTg9JT8kg9WFJTTN1iVY
¶
Disclosure:¶
WyJMRDdSbG5WaHZPRTVoMkFGN280ZlN3IiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBs ZS5jb20iXQ¶
Contents:¶
["LD7RlnVhvOE5h2AF7o4fSw", "email", "johndoe@example.com"]¶
Disclosure for phone_number
:¶
SHA-256 Hash: tAQ3Er6qd3UwQLrZYRe3fMF4J6MXdz5tJMJfJw48I0g
¶
Disclosure:¶
WyI5OUswamRYQjkxUUtUZXd0MEJneDZ3IiwgInBob25lX251bWJlciIsICIrMS0yMDIt NTU1LTAxMDEiXQ¶
Contents:¶
["99K0jdXB91QKTewt0Bgx6w", "phone_number", "+1-202-555-0101"]¶
Disclosure for address
:¶
SHA-256 Hash: lheBqvJLJPRLsoXVF68rmkn9jL73iGCF0V5sJjPlt68
¶
Disclosure:¶
WyJhRG8xSllUX0pkek9meFdPenRqZlJBIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRy ZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9u IjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0¶
Contents:¶
["aDo1JYT_JdzOfxWOztjfRA", "address", {"street_address": "123 Main St", "locality": "Anytown", "region": "Anystate", "country": "US"}]¶
Disclosure for birthdate
:¶
SHA-256 Hash: WkP5oQu7qxPAxLVPKcFuP4rD5TC0T4CekiYi333zQP4
¶
Disclosure:¶
WyJEY1EycGhyQllXRG9VWVdMbVhtYV9BIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAx Il0¶
Contents:¶
["DcQ2phrBYWDoUYWLmXma_A", "birthdate", "1940-01-01"]¶
Disclosure for is_over_18
:¶
SHA-256 Hash: RKE58nhM1GLxUmfvPaZhxNEq8kNplQYnOZlLJosLomY
¶
Disclosure:¶
WyJtYUFIc0xpYWZfdW4za3VDN21Xb0J3IiwgImlzX292ZXJfMTgiLCB0cnVlXQ¶
Contents:¶
["maAHsLiaf_un3kuC7mWoBw", "is_over_18", true]¶
Disclosure for is_over_21
:¶
SHA-256 Hash: goqT4HD2DOmnPF1wNMLNiYuj4SgYtKjfQQHO--CSh0o
¶
Disclosure:¶
WyIyR2hKMHZjQ0xfNzNvNUZrbHV5NndRIiwgImlzX292ZXJfMjEiLCB0cnVlXQ¶
Contents:¶
["2GhJ0vcCL_73o5Fkluy6wQ", "is_over_21", true]¶
Disclosure for is_over_65
:¶
SHA-256 Hash: S7ebWHiOEgQDLG6JcpYkuMKMCb40uxFUSUimK94MuDc
¶
Disclosure:¶
WyI3SHpCQUt3SktBOTNGaWh2QmcxRThRIiwgImlzX292ZXJfNjUiLCB0cnVlXQ¶
Contents:¶
["7HzBAKwJKA93FihvBg1E8Q", "is_over_65", true]¶
This example illustrates how to use the artifacts defined in this specification to secure a payload
that is represented as a W3C Verifiable Credentials Data Model v2.0 [VC_DATA_v2.0]
and uses a JSON-LD object as the claims set. The example uses a content type credential+ld+json
defined in [VC_DATA_v2.0], Section 6.3 in a cty
JOSE Header value.¶
SD-JWT is equivalent to an Issuer-signed W3C Verifiable Credential (W3C VC). Disclosures are sent alongside a VC.¶
A Combined Format for Presentation with a Holder Binding JWT would be equivalent to a Holder-signed Verifiable Presentation as defined in [VC_DATA_v2.0].¶
In this example, Holder Binding is applied and a Combined Format for Presentation is signed
using a Holder's public key passed in a cnf
Claim in the SD-JWT.¶
Below is a non-normative example of an SD-JWT represented as a W3C VC using JSON-LD.¶
The following data will be used in this example:¶
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://w3id.org/vaccination/v1" ], "type": [ "VerifiableCredential", "VaccinationCertificate" ], "issuer": "https://example.com/issuer", "issuanceDate": "2023-02-09T11:01:59Z", "expirationDate": "2028-02-08T11:01:59Z", "name": "COVID-19 Vaccination Certificate", "description": "COVID-19 Vaccination Certificate", "credentialSubject": { "vaccine": { "type": "Vaccine", "atcCode": "J07BX03", "medicinalProductName": "COVID-19 Vaccine Moderna", "marketingAuthorizationHolder": "Moderna Biotech" }, "nextVaccinationDate": "2021-08-16T13:40:12Z", "countryOfVaccination": "GE", "dateOfVaccination": "2021-06-23T13:40:12Z", "order": "3/3", "recipient": { "type": "VaccineRecipient", "gender": "Female", "birthDate": "1961-08-17", "givenName": "Marion", "familyName": "Mustermann" }, "type": "VaccinationEvent", "administeringCentre": "Praxis Sommergarten", "batchNumber": "1626382736", "healthProfessional": "883110000015376" } }¶
The payload of a corresponding SD-JWT looks as follows:¶
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://w3id.org/vaccination/v1" ], "type": [ "VerifiableCredential", "VaccinationCertificate" ], "issuer": "https://example.com/issuer", "issuanceDate": "2023-02-09T11:01:59Z", "expirationDate": "2028-02-08T11:01:59Z", "name": "COVID-19 Vaccination Certificate", "description": "COVID-19 Vaccination Certificate", "credentialSubject": { "_sd": [ "8-N936mMUuXx-Kbf6byQTDOwQoFcoapEvVPbYWiRV5M", "GyDDvOMyEtqsI3vdjbaVSXJZp_WjX_JQIMVqehpr1cU", "MGWjDeD0DvcvG2quwT0zT3wz72HisTJoOtimMc65Qtg", "S7xgnTLcgRqHRipEu0xiEQceAaYh_mfjowFsNZORh4w", "aO2ZezAuMOhmhVv0pQ-U_ZUB4py2hOHa-x7xmGywt8E", "qkaVSrXEw2sbbqS5YdtU1HMNAEjMofTH_6DCxDr91LQ", "ypFwyXOiHzulGDvpY46Jr1nDRexz35FYfBqJWe7xKqc" ], "vaccine": { "_sd": [ "C10ypGMJiTgrgKICDu0TIJ5HSEEhRrsy-XgjPGSsxEk", "HduAC5dITq5LsmcYJChAHrSanA0106-JQdkfqVI-Drs", "HlXX723D-EgjoNr4nQVUbEpAg1Gaxwl74350UXfBBM0" ], "type": "Vaccine" }, "recipient": { "_sd": [ "-KMt3FVtI_7DuaDpFZGIfE751AwqnXKpLVCQaIpl6P4", "8FbBeqe_wV1ES-RU28y8DDkfQv9dlGziVdd9R3jq-fQ", "Cu8JNGQ2WRs6KHKngBKEaU9r6SMfnwoVVYGTPWwvxJc", "YJI42JtoLHmwv2oi45QW6wmINZXTpYBxhD4eWlmEpiw" ], "type": "VaccineRecipient" }, "type": "VaccinationEvent" }, "_sd_alg": "sha-256", "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc", "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ" } } }¶
Disclosures:¶
Disclosure for atcCode
:¶
WyItdjRQVzNldk5TUktHbGNHeHZNbHhRIiwgImF0Y0NvZGUiLCAiSjA3QlgwMyJd¶
Contents:¶
["-v4PW3evNSRKGlcGxvMlxQ", "atcCode", "J07BX03"]¶
SHA-256 Hash: HduAC5dITq5LsmcYJChAHrSanA0106-JQdkfqVI-Drs
¶
Disclosure for medicinalProductName
:¶
WyJqZ2FzWTVvUE94VHVSZXAwYWhVWDR3IiwgIm1lZGljaW5hbFByb2R1Y3ROYW1lIiwg IkNPVklELTE5IFZhY2NpbmUgTW9kZXJuYSJd¶
Contents:¶
["jgasY5oPOxTuRep0ahUX4w", "medicinalProductName", "COVID-19 Vaccine Moderna"]¶
SHA-256 Hash: C10ypGMJiTgrgKICDu0TIJ5HSEEhRrsy-XgjPGSsxEk
¶
Disclosure for marketingAuthorizationHolder
:¶
WyJQRkF5dnIyeG03LTJTTlZUTmdsdjhBIiwgIm1hcmtldGluZ0F1dGhvcml6YXRpb25I b2xkZXIiLCAiTW9kZXJuYSBCaW90ZWNoIl0¶
Contents:¶
["PFAyvr2xm7-2SNVTNglv8A", "marketingAuthorizationHolder", "Moderna Biotech"]¶
SHA-256 Hash: HlXX723D-EgjoNr4nQVUbEpAg1Gaxwl74350UXfBBM0
¶
Disclosure for nextVaccinationDate
:¶
WyJTNFdBd0k0aEFDemx6eDZRclZaODdnIiwgIm5leHRWYWNjaW5hdGlvbkRhdGUiLCAi MjAyMS0wOC0xNlQxMzo0MDoxMloiXQ¶
Contents:¶
["S4WAwI4hACzlzx6QrVZ87g", "nextVaccinationDate", "2021-08-16T13:40:12Z"]¶
SHA-256 Hash: aO2ZezAuMOhmhVv0pQ-U_ZUB4py2hOHa-x7xmGywt8E
¶
Disclosure for countryOfVaccination
:¶
WyJybUtiMkVkbG5MVWFtUGdoSnZ3NURBIiwgImNvdW50cnlPZlZhY2NpbmF0aW9uIiwg IkdFIl0¶
Contents:¶
["rmKb2EdlnLUamPghJvw5DA", "countryOfVaccination", "GE"]¶
SHA-256 Hash: S7xgnTLcgRqHRipEu0xiEQceAaYh_mfjowFsNZORh4w
¶
Disclosure for dateOfVaccination
:¶
WyJhZlNPY2t0cW9kN3VpSTRnaEpDcHNBIiwgImRhdGVPZlZhY2NpbmF0aW9uIiwgIjIw MjEtMDYtMjNUMTM6NDA6MTJaIl0¶
Contents:¶
["afSOcktqod7uiI4ghJCpsA", "dateOfVaccination", "2021-06-23T13:40:12Z"]¶
SHA-256 Hash: qkaVSrXEw2sbbqS5YdtU1HMNAEjMofTH_6DCxDr91LQ
¶
Disclosure for order
:¶
WyJscmhHM1gyOG9QX3VtTGFwRG5lOUlnIiwgIm9yZGVyIiwgIjMvMyJd¶
Contents:¶
["lrhG3X28oP_umLapDne9Ig", "order", "3/3"]¶
SHA-256 Hash: GyDDvOMyEtqsI3vdjbaVSXJZp_WjX_JQIMVqehpr1cU
¶
Disclosure for gender
:¶
WyJMdlNISWdtc280elI5NFJjNm1SUUh3IiwgImdlbmRlciIsICJGZW1hbGUiXQ¶
Contents:¶
["LvSHIgmso4zR94Rc6mRQHw", "gender", "Female"]¶
SHA-256 Hash: Cu8JNGQ2WRs6KHKngBKEaU9r6SMfnwoVVYGTPWwvxJc
¶
Disclosure for birthDate
:¶
WyJGbnlha0RCczNTN3RrZUM0eWxfQjhnIiwgImJpcnRoRGF0ZSIsICIxOTYxLTA4LTE3 Il0¶
Contents:¶
["FnyakDBs3S7tkeC4yl_B8g", "birthDate", "1961-08-17"]¶
SHA-256 Hash: -KMt3FVtI_7DuaDpFZGIfE751AwqnXKpLVCQaIpl6P4
¶
Disclosure for givenName
:¶
WyJxYzA5WWNDcVJ2M1dMT1lsOGZaZFl3IiwgImdpdmVuTmFtZSIsICJNYXJpb24iXQ¶
Contents:¶
["qc09YcCqRv3WLOYl8fZdYw", "givenName", "Marion"]¶
SHA-256 Hash: 8FbBeqe_wV1ES-RU28y8DDkfQv9dlGziVdd9R3jq-fQ
¶
Disclosure for familyName
:¶
WyJUNDVqck1ZbThNa29WU1QtUXlhNGhBIiwgImZhbWlseU5hbWUiLCAiTXVzdGVybWFu biJd¶
Contents:¶
["T45jrMYm8MkoVST-Qya4hA", "familyName", "Mustermann"]¶
SHA-256 Hash: YJI42JtoLHmwv2oi45QW6wmINZXTpYBxhD4eWlmEpiw
¶
Disclosure for administeringCentre
:¶
WyJOeGtSS3hEdEttU2dPNkRteXpiRDB3IiwgImFkbWluaXN0ZXJpbmdDZW50cmUiLCAi UHJheGlzIFNvbW1lcmdhcnRlbiJd¶
Contents:¶
["NxkRKxDtKmSgO6DmyzbD0w", "administeringCentre", "Praxis Sommergarten"]¶
SHA-256 Hash: MGWjDeD0DvcvG2quwT0zT3wz72HisTJoOtimMc65Qtg
¶
Disclosure for batchNumber
:¶
WyJQQ2RiNkpITWZmMENiOVBWNHF3d29nIiwgImJhdGNoTnVtYmVyIiwgIjE2MjYzODI3 MzYiXQ¶
Contents:¶
["PCdb6JHMff0Cb9PV4qwwog", "batchNumber", "1626382736"]¶
SHA-256 Hash: ypFwyXOiHzulGDvpY46Jr1nDRexz35FYfBqJWe7xKqc
¶
Disclosure for healthProfessional
:¶
WyJqUTBHTF9IRkxIdUpKeWFPYkVJa2x3IiwgImhlYWx0aFByb2Zlc3Npb25hbCIsICI4 ODMxMTAwMDAwMTUzNzYiXQ¶
Contents:¶
["jQ0GL_HFLHuJJyaObEIklw", "healthProfessional", "883110000015376"]¶
SHA-256 Hash: 8-N936mMUuXx-Kbf6byQTDOwQoFcoapEvVPbYWiRV5M
¶
The following is a non-normative example of a Combined Format for Presentation for the SD-JWT with a Holder Binding JWT. It only discloses type
, medicinalProductName
, atcCode
of the vaccine, type
of the recipient
, type
, order
and dateOfVaccination
.¶
eyJhbGciOiAiRVMyNTYifQ.eyJAY29udGV4dCI6IFsiaHR0cHM6Ly93d3cudzMub3JnL zIwMTgvY3JlZGVudGlhbHMvdjEiLCAiaHR0cHM6Ly93M2lkLm9yZy92YWNjaW5hdGlvb i92MSJdLCAidHlwZSI6IFsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCAiVmFjY2luYXRpb 25DZXJ0aWZpY2F0ZSJdLCAiaXNzdWVyIjogImh0dHBzOi8vZXhhbXBsZS5jb20vamRvZ SIsICJpc3N1YW5jZURhdGUiOiAiMjAyMy0wMi0wOVQxMTowMTo1OVoiLCAiZXhwaXJhd GlvbkRhdGUiOiAiMjAyOC0wMi0wOFQxMTowMTo1OVoiLCAibmFtZSI6ICJDT1ZJRC0xO SBWYWNjaW5hdGlvbiBDZXJ0aWZpY2F0ZSIsICJkZXNjcmlwdGlvbiI6ICJDT1ZJRC0xO SBWYWNjaW5hdGlvbiBDZXJ0aWZpY2F0ZSIsICJjcmVkZW50aWFsU3ViamVjdCI6IHsiX 3NkIjogWyI4LU45MzZtTVV1WHgtS2JmNmJ5UVRET3dRb0Zjb2FwRXZWUGJZV2lSVjVNI iwgIkd5RER2T015RXRxc0kzdmRqYmFWU1hKWnBfV2pYX0pRSU1WcWVocHIxY1UiLCAiT UdXakRlRDBEdmN2RzJxdXdUMHpUM3d6NzJIaXNUSm9PdGltTWM2NVF0ZyIsICJTN3hnb lRMY2dScUhSaXBFdTB4aUVRY2VBYVloX21mam93RnNOWk9SaDR3IiwgImFPMlplekF1T U9obWhWdjBwUS1VX1pVQjRweTJoT0hhLXg3eG1HeXd0OEUiLCAicWthVlNyWEV3MnNiY nFTNVlkdFUxSE1OQUVqTW9mVEhfNkRDeERyOTFMUSIsICJ5cEZ3eVhPaUh6dWxHRHZwW TQ2SnIxbkRSZXh6MzVGWWZCcUpXZTd4S3FjIl0sICJ2YWNjaW5lIjogeyJfc2QiOiBbI kMxMHlwR01KaVRncmdLSUNEdTBUSUo1SFNFRWhScnN5LVhnalBHU3N4RWsiLCAiSGR1Q UM1ZElUcTVMc21jWUpDaEFIclNhbkEwMTA2LUpRZGtmcVZJLURycyIsICJIbFhYNzIzR C1FZ2pvTnI0blFWVWJFcEFnMUdheHdsNzQzNTBVWGZCQk0wIl0sICJ0eXBlIjogIlZhY 2NpbmUifSwgInJlY2lwaWVudCI6IHsiX3NkIjogWyItS010M0ZWdElfN0R1YURwRlpHS WZFNzUxQXdxblhLcExWQ1FhSXBsNlA0IiwgIjhGYkJlcWVfd1YxRVMtUlUyOHk4RERrZ lF2OWRsR3ppVmRkOVIzanEtZlEiLCAiQ3U4Sk5HUTJXUnM2S0hLbmdCS0VhVTlyNlNNZ m53b1ZWWUdUUFd3dnhKYyIsICJZSkk0Mkp0b0xIbXd2Mm9pNDVRVzZ3bUlOWlhUcFlCe GhENGVXbG1FcGl3Il0sICJ0eXBlIjogIlZhY2NpbmVSZWNpcGllbnQifSwgInR5cGUiO iAiVmFjY2luYXRpb25FdmVudCJ9LCAiaXNzIjogImh0dHBzOi8vZXhhbXBsZS5jb20va XNzdWVyIiwgImlhdCI6IDE1MTYyMzkwMjIsICJleHAiOiAxNTE2MjQ3MDIyLCAiX3NkX 2FsZyI6ICJzaGEtMjU2IiwgImNuZiI6IHsiandrIjogeyJrdHkiOiAiRUMiLCAiY3J2I jogIlAtMjU2IiwgIngiOiAiVENBRVIxOVp2dTNPSEY0ajRXNHZmU1ZvSElQMUlMaWxEb HM3dkNlR2VtYyIsICJ5IjogIlp4amlXV2JaTVFHSFZXS1ZRNGhiU0lpcnNWZnVlY0NFN nQ0alQ5RjJIWlEifX19.Z5zQzcPFTkeNt49nS_Vtmuq49cpn6PuE3Y3UmFiKOxT9rlBx jmCwb3UqPzuyvL5G1vhswELD2d3iakMvtq3jgQ~WyJscmhHM1gyOG9QX3VtTGFwRG5lO UlnIiwgIm9yZGVyIiwgIjMvMyJd~WyJhZlNPY2t0cW9kN3VpSTRnaEpDcHNBIiwgImRh dGVPZlZhY2NpbmF0aW9uIiwgIjIwMjEtMDYtMjNUMTM6NDA6MTJaIl0~WyJqZ2FzWTVv UE94VHVSZXAwYWhVWDR3IiwgIm1lZGljaW5hbFByb2R1Y3ROYW1lIiwgIkNPVklELTE5 IFZhY2NpbmUgTW9kZXJuYSJd~WyItdjRQVzNldk5TUktHbGNHeHZNbHhRIiwgImF0Y0N vZGUiLCAiSjA3QlgwMyJd~eyJhbGciOiAiRVMyNTYifQ.eyJub25jZSI6ICJYWk9VY28 xdV9nRVBrbnhTNzhzV1dnIiwgImF1ZCI6ICJodHRwczovL2V4YW1wbGUuY29tL3Zlcml maWVyIiwgImlhdCI6IDE2NzYwNDg5NzV9.QVDqrgqbWpAlnC1pl69q-FmT1BomWLjD6g xfhhKlZVq7SZheXzXEBDdVf3rWAzJOFOMk84tAp3wjLb9HQrckpA¶
After the validation, the Verifier will have the following data for further processing:¶
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://w3id.org/vaccination/v1" ], "type": [ "VerifiableCredential", "VaccinationCertificate" ], "issuer": "https://example.com/issuer", "issuanceDate": "2023-02-09T11:01:59Z", "expirationDate": "2028-02-08T11:01:59Z", "name": "COVID-19 Vaccination Certificate", "description": "COVID-19 Vaccination Certificate", "credentialSubject": { "vaccine": { "type": "Vaccine", "medicinalProductName": "COVID-19 Vaccine Moderna", "atcCode": "J07BX03" }, "recipient": { "type": "VaccineRecipient" }, "type": "VaccinationEvent", "order": "3/3", "dateOfVaccination": "2021-06-23T13:40:12Z" }, "_sd_alg": "sha-256", "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc", "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ" } } }¶
As described in Section 5.1.1, the Disclosure structure is JSON containing salt and the cleartext content of a claim, which is base64url encoded. The encoded value is the input used to calculate a digest for the respective claim. The inclusion of digest value in the signed JWT ensures the integrity of the claim value. Using encoded content as the input to the integrity mechanism is conceptually similar to the approach in JWS and particularly useful when the content, like JSON, can have differences but be semantically equivalent. Some further discussion of the considerations around this design decision follows.¶
When receiving an SD-JWT with associated Disclosures, a Verifier must be able to re-compute digests of the disclosed claim values and, given the same input values, obtain the same digest values as signed by the Issuer.¶
Usually, JSON-based formats transport claim values as simple properties of a JSON object such as this:¶
... "family_name": "Möbius", "address": { "street_address": "Schulstr. 12", "locality": "Schulpforta" } ...¶
However, a problem arises when computation over the data need to be performed and verified, like signing or computing digests. Common signature schemes require the same byte string as input to the signature verification as was used for creating the signature. In the digest approach outlined above, the same problem exists: for the Issuer and the Verifier to arrive at the same digest, the same byte string must be hashed.¶
JSON, however, does not prescribe a unique encoding for data, but allows for variations in the encoded string. The data above, for example, can be encoded as¶
... "family_name": "M\u00f6bius", "address": { "street_address": "Schulstr. 12", "locality": "Schulpforta" } ...¶
or as¶
... "family_name": "Möbius", "address": {"locality":"Schulpforta", "street_address":"Schulstr. 12"} ...¶
The two representations "M\u00f6bius"
and "Möbius"
are very different on the byte-level, but yield
equivalent objects. Same for the representations of address
, varying in white space and order of elements in the object.¶
The variations in white space, ordering of object properties, and encoding of Unicode characters are all allowed by the JSON specification, including further variations, e.g., concerning floating-point numbers, as described in [RFC8785]. Variations can be introduced whenever JSON data is serialized or deserialized and unless dealt with, will lead to different digests and the inability to verify signatures.¶
There are generally two approaches to deal with this problem:¶
Mixed approaches are conceivable, i.e., transferring both the original JSON data plus a string suitable for computing a digest, but such approaches can easily lead to undetected inconsistencies resulting in time-of-check-time-of-use type security vulnerabilities.¶
In this specification, the source string hardening approach is used, as it allows for simple and reliable interoperability without the requirement for a canonicalization library. To harden the source string, any serialization format that supports the necessary data types could be used in theory, like protobuf, msgpack, or pickle. In this specification, JSON is used and plain text values of each Disclosure are encoded using base64url-encoding for transport. This approach means that SD-JWTs can be implemented purely based on widely available JWT, JSON, and Base64 encoding and decoding libraries.¶
A Verifier can then easily check the digest over the source string before extracting the original JSON data. Variations in the encoding of the source string are implicitly tolerated by the Verifier, as the digest is computed over a predefined byte string and not over a JSON object.¶
It is important to note that the Disclosures are neither intended nor suitable for direct consumption by an application that needs to access the disclosed claim values after the verification by the Verifier. The Disclosures are only intended to be used by a Verifier to check the digests over the source strings and to extract the original JSON data. The original JSON data is then used by the application. See Section 6.2 for details.¶
[[ To be removed from the final specification ]]¶
-03¶
none
)¶
-02¶
_sd
claim per level.¶
_sd_alg
)¶
-01¶
_sd_hash_alg
renamed to sd_digest_derivation_alg
¶
sd_disclosure
in II-Disclosures renamed to sd_ii_disclosures
¶
sd_disclosure
in HS-Disclosures renamed to sd_hs_disclosures
¶
sd_hs_disclosure
and SD-JWT¶
cnf
structure in examples¶
-00¶
[[ pre Working Group Adoption: ]]¶
-02¶
hash_alg
renamed to _sd_hash_alg
¶
-01¶
hash_alg
claim¶
_sd
to sd_digests
and sd_release
¶
-00¶