LogoLogo
ProductsCommunityGitHubShare Feedback
SSI Kit
SSI Kit
  • General
    • Introduction
    • Transition To The Community Stack
    • SSI Kit | Basics
      • Overview
      • Functionality
      • Components
    • SSI Kit
      • SSI Flavors & Ecosystems
        • Trust Registries
        • Keys
        • Decentralized Identifiers (DIDs)
        • Verifiable Credentials (VCs)
        • Data Exchange Protocols
      • Architecture
        • Low-Level Service Abstraction
        • Ecosystem Abstraction
        • High-Level Interfaces / APIs
      • Use Cases
      • Self-Sovereign Identity (SSI)
        • SSI | Basics
        • Technologies & Concepts
          • Registries
          • Decentralised Identifiers (DIDs)
          • Verifiable Credentials (VCs)
          • Verifiable Presentations (VPs)
          • Data Exchange (Protocols)
  • Getting started
    • Quick Start
    • REST API
      • Signatory API - For Issuers
      • Custodian API - For Holders
        • Key management
        • Did management
        • Credentials management
      • Auditor API - For Verifiers
      • Core API
        • Cryptographic keys
        • Decentralised-Identifiers
        • Verifiable-Credentials
      • API Serving Configs
    • Dependency (JVM)
      • Java Examples
      • Kotlin Examples
    • CLI | Command Line Interface
      • Key Management
      • Decentralized Identifiers
      • Verifiable Credentials
      • OpenID Connect (OIDC)
    • Building the Project
      • Docker Build
      • Local Build
    • Project Configurations
    • Demo
  • Ecosystems
    • EBSI
      • Basics
      • Use Cases & Flow Diagrams
      • Command line interface
        • DID Registration
      • REST API
      • Usage / examples
        • Onboarding & DIDs
        • Build end-to-end use cases
    • IOTA
      • OIDC4VP profile for Login-with-IOTA
      • Login With IOTA Demo
    • Velocity
      • Basics
        • Onboarding
        • Issuing
        • Inspection
      • Integration with SSIKit
      • Command line interface
        • Onboarding
        • Issuing
        • Inspection
    • cheqd
      • Integration architecture
      • Create DID
      • Issue VC
      • Verify VC
  • Tutorials
    • My First VC
    • Advanced VC
  • Concepts
    • Credential Templates
    • Verification Policies
      • Static Policies
      • Parameterized Policies
      • Dynamic/Custom Policies
        • Creating Dynamic Policies
        • Using Dynamic Policies
        • Removing Dynamic Policies
        • Dynamic Policies | Data Classes
    • Selective Disclosure
      • Intro
      • Issuing a SD-JWT Credential
      • Verifying a SD-JWT Credential
    • Credential Statuses
      • StatusList2021Entry
      • SimpleCredentialStatus2022
      • Issue credentials with credentialStatus
      • REST API
        • Check the status of a credential
        • Revoke a credential
      • CLI
        • Check the status of a credential
        • Revoke a credential
    • DID Web
    • Open Policy Agent (OPA)
      • Setup
    • OpenID Connect (OIDC)
      • Credential Issuance
        • OIDC4CI | Example
      • Presentation Exchange
        • OIDC4VP | Example
    • Delegation and Mandates
  • Community
    • Discord
    • Twitter
    • Newsletter
    • GitHub Discussions
  • DEVELOPER RELATIONS
    • Contribute
    • Roadmap
    • Share Feedback
    • Contact
  • Product Editions
    • Open Source | Always Free
    • Enterprise | Self-Managed
    • Cloud Platform | Managed
Powered by GitBook
On this page
  • SD-JWT Credential Issuance Process
  • Issuance in Action
  • Demo Video

Was this helpful?

Export as PDF
  1. Concepts
  2. Selective Disclosure

Issuing a SD-JWT Credential

Learn about issuing SD-JWT credentials which includes hashing, creating disclosures and adding decoy hashes

PreviousIntroNextVerifying a SD-JWT Credential

Last updated 1 month ago

Was this helpful?

SD-JWT Credential Issuance Process

  1. Credential Creation: The issuer first creates the credential, as usual.

  2. Conversion to SD-JWT Credential: The issuer then transforms the credential into an SD-JWT. This is done by hashing all or only a subset of claims, adding decoy hashes, and preparing disclosures. At the end, the SD-JWT credential can contain plain-text claims next to disclosable ones.

  3. Claim Hashing: The claim is transformed into a disclosure, which is a plain-text representations of the claim, by concatenating the attribute name and value, then prefixing it with a salt. The salt prevents attackers from guessing plain-text values via dictionary attacks. This is then converted to a base64 string, which will represent the disclosure. For example, the disclosure may look like this (salt + attribute name + value): [ “dC12Y2xpYi9tYXN0ZXI”, “given_name”, “John” ]. The disclosure is then put into a hash function, and the result gets included in the SD-JWT.

  4. Adding Decoy Hashes: At this point, decoy hashes are also added to the SD-JWT. These decoy hashes are essentially dummy values that help conceal the actual number of claims a credential holds. By using decoy hashes, the issuer can prevent potential observers from determining how many claims are contained within the credential based on the number of hashes.

  5. SD-JWT Credential Transfer to Holder: The issuer sends the SD-JWT and all disclosures to the holder. Because the holder now has the SD-JWT credential as well as all the disclosures, he can read the entire content of the credential. This allows the holder to decide which disclosures to send alongside the SD-JWT in a transaction with a verifier.

  6. Transfer Format: On transfer, the SD-JWT is shared with the concatenated disclosures using the ~ sign. An example of this format would be:

eyJraWQiOiI5MmJlMTAzYjRkZmY0OGYxYmE5ODc4ZGQyNmZhZjcxZSIsImN0eSI6ImNyZWRlbnRpYWwtY2xhaW1zLXNldCtqc29uIiwidHlwIjoidmMrc2Qtand0IiwiYWxnIjoiRWREU0EifQ.eyJjcmVkZW50aWFsU2NoZW1hIjp7ImlkIjoiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dhbHQtaWQvd2FsdGlkLXNzaWtpdC12Y2xpYi9tYXN0ZXIvc3JjL3Rlc3QvcmVzb3VyY2VzL3NjaGVtYXMvVmVyaWZpYWJsZUlkLmpzb24iLCJ0eXBlIjoiRnVsbEpzb25TY2hlbWFWYWxpZGF0b3IyMDIxIn0sImV2aWRlbmNlIjpbeyJkb2N1bWVudFByZXNlbmNlIjpbIlBoeXNpY2FsIl0sInZlcmlmaWVyIjoiZGlkOmVic2k6MkE5Qlo5U1VlNkJhdGFjU3B2czFWNUNkakh2THBRN2JFc2kySmI2TGRIS25ReGFOIiwiZXZpZGVuY2VEb2N1bWVudCI6WyJQYXNzcG9ydCJdLCJ0eXBlIjpbIkRvY3VtZW50VmVyaWZpY2F0aW9uIl0sInN1YmplY3RQcmVzZW5jZSI6IlBoeXNpY2FsIn1dLCJpc3N1YW5jZURhdGUiOiIyMDIxLTA4LTMxVDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7InBlcnNvbmFsSWRlbnRpZmllciI6IjA5MDQwMDgwODRIIiwiZmlyc3ROYW1lIjoiSmFuZSIsIl9zZCI6WyJuNWRYOEVpTUNoQ1hBR0o3elZCM1duQjc4Y3lBVFp3T1hwVkpCTUdOUzhzIiwiemFxMTNsa2lHLTd2am90SFppM0psSmhwS2JtUjFTVnV6Q3pLYVZYOUZRUSIsInhyYjdTOFZsNlctb0dMaVVQcTVlMmplVFpKVk5mYmRtNW9KNjd0VlVQem8iLCJwT0Jmb3hmQndqQUNPbXZ4aTNUSTc0RDN4Y2FwZS1RWVlGeUNPZEpPel9VIiwiRm1ZcmFmbWotUW9lbE1sSkQtVTN2OVgwS3hXTkZwelhwRl9McVc2dkZ0byJdLCJwbGFjZU9mQmlydGgiOiJMSUxMRSwgRlJBTkNFIiwiZ2VuZGVyIjoiRkVNQUxFIiwiZmFtaWx5TmFtZSI6IkRPRSIsImlkIjoiZGlkOmVic2k6MkFFTUFxWFdLWU11MUpIUEFnR2NnYTRkeHU3VGhnZmdOOTVWeUpCSkdaYlNKVXRwIiwibmFtZUFuZEZhbWlseU5hbWVBdEJpcnRoIjoiSmFuZSBET0UiLCJjdXJyZW50QWRkcmVzcyI6WyIxIEJvdWxldmFyZCBkZSBsYSBMaWJlcnTDqSwgNTk4MDAgTGlsbGUiXX0sIl9zZF9hbGciOiJzaGEtMjU2IiwiaWQiOiJ1cm46dXVpZDozYWRkOTRmNC0yOGVjLTQyYTEtODcwNC00ZTRhYTUxMDA2YjQiLCJ2YWxpZEZyb20iOiIyMDIxLTA4LTMxVDAwOjAwOjAwWiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJWZXJpZmlhYmxlQXR0ZXN0YXRpb24iLCJWZXJpZmlhYmxlSWQiXSwiaXNzdWVkIjoiMjAyMS0wOC0zMVQwMDowMDowMFoiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpc3N1ZXIiOiJkaWQ6ZWJzaToyQTlCWjlTVWU2QmF0YWNTcHZzMVY1Q2RqSHZMcFE3YkVzaTJKYjZMZEhLblF4YU4ifQ.5TZ1n6iDHtW3lnKA_7ofSQ-BWyvEr39LThGdIc1OMgUejG6JF6blGkTqcoaQABQJKq6pFgkhjrYcpDG8QcObDA~~

Issuance in Action

Using either the CLI, Kotlin or REST option, you can start issuing your SD-JWT credential.

, if you never used the SSi-Kit before. I will be using ssikit as an alias for ./ssikit.sh in this section.

DID creation

Creating a did:key for our SD-JWT credential. Please refer to for all options.

ssikit did create

Example Response

walt.id SSI Kit 1.SNAPSHOT (running on Java 18.0.1+10-24)

Creating did:id.walt.cli.did.KeyMethodOption@59c04bee (key: 98de22f79c7e445dbedc0c72a18f6f9a)

Results:


DID created: did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a


DID document (below, JSON):

{
    "assertionMethod" : [
        "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a"
    ],
    "authentication" : [
        "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a"
    ],
    "capabilityDelegation" : [
        "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a"
    ],
    "capabilityInvocation" : [
        "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a"
    ],
    "@context" : "https://www.w3.org/ns/did/v1",
    "id" : "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
    "keyAgreement" : [
        "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6LSdemtq8mkV4nRKqvQvGkvs1JzSm4sCKKWNh6KkVox1vFn"
    ],
    "verificationMethod" : [
        {
            "controller" : "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
            "id" : "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
            "publicKeyBase58" : "FMZP5xZMrXr8cveAR28hr1s5wnybptiz5RddaM7KqnHC",
            "type" : "Ed25519VerificationKey2019"
        },
        {
            "controller" : "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
            "id" : "did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a#z6LSdemtq8mkV4nRKqvQvGkvs1JzSm4sCKKWNh6KkVox1vFn",
            "publicKeyBase58" : "2ybjJpxtPc4gETYePdEyYR6WbcXkVi9MViNeG3ARJYV2",
            "type" : "X25519KeyAgreementKey2019"
        }
    ]
}

Issue VC with SD-JWT format

We will be using the VerifiableId credential template for this example, but you can use whatever template you want. When issuing we specify the format of the VC as SD-JWT, the fields which we want to make selectily discloable and the number of decoy digests we want to include (optiona).

ssikit vc issue -s did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a \
-i did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a \
-y SD_JWT -t VerifiableId \
--sd credentialSubject \
--sd credentialSubject.dateOfBirth \
--num-decoys 2 \
--interactive vc.txt

Options:

  • -s, --subject-did: DID of the subject

  • -i, --issuer-did: DID of the issuer

  • -y, --proof-type: Either JWT, LD_PROOF or SD_JWT

  • -t, --template: VC template, e.g VerifiableId

  • --sd, --selective-disclosure: Path to selectively disclosable fields (if supported by chosen proof type), in a simplified JsonPath format, can be specified multiple times, e.g credentialSubject.dataOfBirth

  • --num-decoys: Number of SD-JWT decoy digests to add (fixed mode), or max num of decoy digests (random mode)

  • --interactive: Interactively prompt for VC data to fill in

  • vc.txt: Path to output the generated VC

Example Response

Receiving a JWT token with disclosures appended via '~'.

eyJraWQiOiJkaWQ6a2V5Ono2TWt0b3BSZ0Nvb0M1TGJqUlVzNmI2WWg3UjVtTkZURW15TG1TWVpRZDVMbTE0YSN6Nk1rdG9wUmdDb29DNUxialJVczZiNlloN1I1bU5GVEVteUxtU1laUWQ1TG0xNGEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJzdWIiOiJkaWQ6a2V5Ono2TWt0b3BSZ0Nvb0M1TGJqUlVzNmI2WWg3UjVtTkZURW15TG1TWVpRZDVMbTE0YSIsIm5iZiI6MTY4NjU3OTY5NCwiaXNzIjoiZGlkOmtleTp6Nk1rdG9wUmdDb29DNUxialJVczZiNlloN1I1bU5GVEVteUxtU1laUWQ1TG0xNGEiLCJpYXQiOjE2ODY1Nzk2OTQsInZjIjp7InR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJWZXJpZmlhYmxlQXR0ZXN0YXRpb24iLCJWZXJpZmlhYmxlSWQiXSwiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiXSwiaWQiOiJ1cm46dXVpZDoyZDM1YWFkMC1jY2UyLTQyODYtYWRmNy1jNGY5YTJlNTdmOTYiLCJpc3N1ZXIiOiJkaWQ6a2V5Ono2TWt0b3BSZ0Nvb0M1TGJqUlVzNmI2WWg3UjVtTkZURW15TG1TWVpRZDVMbTE0YSIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDYtMTJUMTQ6MjE6MzRaIiwiaXNzdWVkIjoiMjAyMy0wNi0xMlQxNDoyMTozNFoiLCJ2YWxpZEZyb20iOiIyMDIzLTA2LTEyVDE0OjIxOjM0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vd2FsdC1pZC93YWx0aWQtc3Npa2l0LXZjbGliL21hc3Rlci9zcmMvdGVzdC9yZXNvdXJjZXMvc2NoZW1hcy9WZXJpZmlhYmxlSWQuanNvbiIsInR5cGUiOiJGdWxsSnNvblNjaGVtYVZhbGlkYXRvcjIwMjEifSwiZXZpZGVuY2UiOlt7ImRvY3VtZW50UHJlc2VuY2UiOlsiUGh5c2ljYWwiXSwiZXZpZGVuY2VEb2N1bWVudCI6WyJQYXNzcG9ydCJdLCJzdWJqZWN0UHJlc2VuY2UiOiJQaHlzaWNhbCIsInR5cGUiOlsiRG9jdW1lbnRWZXJpZmljYXRpb24iXSwidmVyaWZpZXIiOiJkaWQ6ZWJzaToyQTlCWjlTVWU2QmF0YWNTcHZzMVY1Q2RqSHZMcFE3YkVzaTJKYjZMZEhLblF4YU4ifV0sIl9zZCI6WyJDQVlnNmc2bXJJTkFtdURDMzVKbXFMYy1DT1JBNC1MV2Fua2hKVWdVeHhzIl19LCJqdGkiOiJ1cm46dXVpZDoyZDM1YWFkMC1jY2UyLTQyODYtYWRmNy1jNGY5YTJlNTdmOTYifQ.xHwzXlrx0qS3grAQXWbZAX26Vg8enUegcVGMktl22Tr_ir19GHNidD6ZgEAJzlfmYS08hQDTAuDxsxE5J-ZvCA~~

Parsing the response

Viewing body of SD-JWT in JSON format

ssikit vc parse -c vc.txt

Options:

  • -c: credential content or file path

Example Responsen

{
    "type":[
        "VerifiableCredential",
        "VerifiableAttestation",
        "VerifiableId"
    ],
    "@context":[
        "https://www.w3.org/2018/credentials/v1"
    ],
    "id":"urn:uuid:2d35aad0-cce2-4286-adf7-c4f9a2e57f96",
    "issuer":"did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
    "issuanceDate":"2023-06-12T14:21:34Z",
    "issued":"2023-06-12T14:21:34Z",
    "validFrom":"2023-06-12T14:21:34Z",
    "credentialSchema":{
        "id":"https://raw.githubusercontent.com/walt-id/waltid-ssikit-vclib/master/src/test/resources/schemas/VerifiableId.json",
        "type":"FullJsonSchemaValidator2021"
    },
    "credentialSubject":{
        "id":"did:key:z6MktopRgCooC5LbjRUs6b6Yh7R5mNFTEmyLmSYZQd5Lm14a",
        "currentAddress":[
            "Vienna"
        ],
        "familyName":"Baumann",
        "firstName":"Tamino",
        "gender":"Male",
        "nameAndFamilyNameAtBirth":"Jane DOE",
        "personalIdentifier":"0904008084H",
        "placeOfBirth":"Munich",
        "dateOfBirth":"2023"
    },
    "evidence":[
        {
            "documentPresence":[
                "Physical"
            ],
            "evidenceDocument":[
                "Passport"
            ],
            "subjectPresence":"Physical",
            "type":[
                "DocumentVerification"
            ],
            "verifier":"did:ebsi:2A9BZ9SUe6BatacSpvs1V5CdjHvLpQ7bEsi2Jb6LdHKnQxaN"
        }
    ]
}

coming soon

Demo Video

Setup section
DIDs section