/SD-JWT-Kotlin

A Kotlin implementation of the Selective Disclosure JWT (SD-JWT) spec.

Primary LanguageKotlinMIT LicenseMIT

SD-JWT Implementation in Kotlin

This is a Kotlin implementation of the Selective Disclosure for JWTs spec using the Nimbus JOSE + JWT library.

Up to date with draft version: 02

Checking Out the Implementation

In the SdJwtKtTest.kt file there are examples that show how the library can be used on the issuance, wallet and verifier side.

Running the Examples

First Possibility

If you have Docker installed you can simply run:

  1. docker build -t sd-jwt .
  2. docker run -it --rm sd-jwt

Second Possibility (Linux)

  1. Install Java version 17 or newer (e.g. sudo apt install -y openjdk-17-jdk)
  2. Run tests with the gradle wrapper: ./gradlew test --tests SdJwtKtTest -i -PossrhUsername= -PossrhPassword=

Import into Gradle Project

build.gradle

plugins {
    /* ... */
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.7.10'
}

dependencies {
    /* ... */
    implementation 'org.sd-jwt:sd-jwt-kotlin:0.0.0'

    // https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt
    implementation("com.nimbusds:nimbus-jose-jwt:9.24.3")
    // For ED25519 key pairs
    implementation("com.google.crypto.tink:tink:1.7.0")

    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0")
}

Library Usage

Initialization

First you need to define your credential as a kotlinx serializable data class.

@Serializable
data class SimpleTestCredential(
    @SerialName("given_name") val givenName: String? = null,
    @SerialName("family_name") val familyName: String? = null,
    val email: String? = null,
    val b: Boolean? = null,
    val age: Int? = null
)

Then you need a few variables to get started.

val verifier = "http://verifier.example.com"
val issuer = "http://issuer.example.com"

val issuerKeyJson = """{"kty":"OKP","d":"Pp1foKt6rJAvx0igrBEfOgrT0dgMVQDHmgJZbm2h518","crv":"Ed25519","kid":"IssuerKey","x":"1NYF4EFS2Ov9hqt35fVt2J-dktLV29hs8UFjxbOXnho"}"""
val issuerKey = OctetKeyPair.parse(issuerKeyJson)

val trustedIssuers = mutableMapOf<String, String>(issuer to issuerKey.toPublicJWK().toJSONString())

Issuer Creating the Credential

val claims = SimpleTestCredential("Alice", "Wonderland", "alice@example.com", false, 21)
val credential = createCredential(claims, null, issuer, issuerKey)

Wallet Creating the Presentation

val releaseClaims = SimpleTestCredential(givenName = "",  email = "", age = 0) // Non-null claims will be revealed
val presentation = createPresentation(credential, releaseClaims, verifier, "12345", null)

Verifier Parsing and Verifying the Credential

val verifiedSimpleTestCredential = verifyPresentation<SimpleTestCredential>(presentation, trustedIssuers, "12345", verifier)