SdJwt.Net 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package SdJwt.Net --version 1.0.0
                    
NuGet\Install-Package SdJwt.Net -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SdJwt.Net" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SdJwt.Net" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SdJwt.Net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SdJwt.Net --version 1.0.0
                    
#r "nuget: SdJwt.Net, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SdJwt.Net@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SdJwt.Net&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SdJwt.Net&version=1.0.0
                    
Install as a Cake Tool

SdJwt.Net Core - RFC 9901 Implementation

NuGet Version License

A production-ready .NET library for Selective Disclosure JSON Web Tokens (SD-JWTs) compliant with RFC 9901. This is the core library that provides fundamental SD-JWT functionality with enhanced security, performance optimization, and comprehensive multi-platform support.

Features

  • RFC 9901 Compliant: Complete implementation of Selective Disclosure for JSON Web Tokens
  • JWS JSON Serialization: Full support for Flattened and General JSON formats (RFC 9901 Section 8)
  • Enhanced Security: Blocks weak algorithms (MD5, SHA-1), enforces approved SHA-2 family
  • Multi-Platform: .NET 8, 9, and .NET Standard 2.1 with platform-specific optimizations
  • Production Ready: Battle-tested with comprehensive tests and security hardening

Installation

dotnet add package SdJwt.Net

Quick Start

SD-JWT Structure

graph LR
    subgraph SdJwtCompactFormat[SD-JWT Compact Format]
        Header[Base64url Header: alg, typ]
        Payload[Base64url Payload: iss, iat, exp, _sd hashes, _sd_alg sha-256]
        Sig[Base64url Signature]
        Disc1[~Disclosure 1: salt + claim_name + value]
        Disc2[~Disclosure 2: salt + claim_name + value]
        KB[~KB-JWT: nonce + aud + iat]
    end

    Header -.->|.|  Payload
    Payload -.->|.| Sig
    Sig -.->|~| Disc1
    Disc1 -.->|~| Disc2
    Disc2 -.->|~| KB

    style Header fill:#1b4332,color:#fff
    style Payload fill:#2d6a4f,color:#fff
    style Sig fill:#40916c,color:#fff
    style KB fill:#d62828,color:#fff

Basic SD-JWT Creation

using SdJwt.Net.Issuer;
using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography;

// Create signing key
using var key = ECDsa.Create();
var signingKey = new ECDsaSecurityKey(key) { KeyId = "issuer-key-1" };
var holderJwk = JsonWebKeyConverter.ConvertFromSecurityKey(
    new ECDsaSecurityKey(ECDsa.Create()) { KeyId = "holder-key-1" });

// Create SD-JWT issuer
var issuer = new SdIssuer(signingKey, SecurityAlgorithms.EcdsaSha256);

// Define claims with selective disclosure
var claims = new JwtPayload
{
    ["iss"] = "https://issuer.example.com",
    ["given_name"] = "John",
    ["family_name"] = "Doe",
    ["email"] = "john.doe@example.com",
    ["address"] = new {
        street = "123 Main St",
        city = "Anytown",
        state = "CA"
    }
};

// Configure selective disclosure
var options = new SdIssuanceOptions
{
    DisclosureStructure = new
    {
        given_name = true,
        family_name = true,
        email = true,
        address = new { city = true, state = true }
    }
};

// Issue SD-JWT
var result = issuer.Issue(claims, options, holderJwk);

Holder Creates Presentation

using SdJwt.Net.Holder;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;

// Create holder from issuance
var holder = new SdJwtHolder(result.Issuance);
using var holderPrivateEcdsa = ECDsa.Create();
var holderPrivateKey = new ECDsaSecurityKey(holderPrivateEcdsa) { KeyId = "holder-key-1" };
var kbPayload = new JwtPayload
{
    ["aud"] = "https://verifier.example.com",
    ["nonce"] = "job-application-2024-12345",
    ["iat"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};

// Create selective presentation (only disclose email and city)
var presentation = holder.CreatePresentation(
    disclosure => disclosure.ClaimName == "email" || disclosure.ClaimName == "city",
    kbPayload, holderPrivateKey, SecurityAlgorithms.EcdsaSha256);

// For SD-JWT (without KB-JWT), compact output follows RFC 9901 and ends with "~".
// For SD-JWT+KB, the final component is the KB-JWT (no trailing empty component).

Verification

sequenceDiagram
    participant Holder as Holder (Wallet)
    participant Verifier as Verifier

    Holder->>Verifier: VP Token (SD-JWT~email~KB-JWT)

    Note over Verifier: Step 1 - Parse & split
    Verifier->>Verifier: Split on ~ separator
    Verifier->>Verifier: Decode header / payload / sig

    Note over Verifier: Step 2 - Verify issuer signature
    Verifier->>Verifier: Resolve issuer JWKS
    Verifier->>Verifier: Validate JWT signature

    Note over Verifier: Step 3 - Reconstruct disclosures
    Verifier->>Verifier: For each disclosure: SHA-256(salt+name+value)
    Verifier->>Verifier: Verify hash appears in _sd array

    Note over Verifier: Step 4 - Verify Key Binding
    Verifier->>Verifier: Verify KB-JWT signature with holder key
    Verifier->>Verifier: Check nonce matches expected value
    Verifier->>Verifier: Check aud matches verifier URL

    Verifier-->>Holder: Verification Result + Revealed Claims
using SdJwt.Net.Verifier;

// Create verifier with key resolver
var verifier = new SdVerifier(async issuer =>
{
    // Resolve issuer's public key from trusted source
    return await ResolveIssuerKeyAsync(issuer);
});

// Verify presentation
var validationParams = new TokenValidationParameters
{
    ValidateIssuer = true,
    ValidIssuer = "https://issuer.example.com",
    ValidateAudience = false,
    ValidateLifetime = true
};
var kbParams = new TokenValidationParameters
{
    ValidateAudience = true,
    ValidAudience = "https://verifier.example.com",
    ValidateLifetime = true
};

// Verify presentation with expected nonce for replay protection
var expectedNonce = "job-application-2024-12345";
var result = await verifier.VerifyAsync(presentation, validationParams, kbParams, expectedNonce);

if (result.KeyBindingVerified)
{
    Console.WriteLine($"Key Binding Verified. Nonce: {result.KeyBindingJwtPayload?["nonce"]}");
}

// Optional strict policy controls (strict mode is enabled by default)
var verifierOptions = new SdVerifierOptions
{
    StrictMode = true,
    KeyBinding = new KeyBindingValidationPolicy
    {
        RequireKeyBinding = true,
        ExpectedAudience = "https://verifier.example.com",
        MaxKeyBindingJwtAge = TimeSpan.FromMinutes(5)
    }
};

Security Features

  • Algorithm Enforcement: Blocks MD5, SHA-1; enforces SHA-2 family
  • Constant-time Operations: Protection against timing attacks
  • Input Validation: Comprehensive validation throughout APIs
  • Cross-platform Security: Consistent guarantees across platforms

Documentation

For comprehensive examples and advanced usage, see the main repository.

License

Licensed under the Apache License 2.0.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (11)

Showing the top 5 NuGet packages that depend on SdJwt.Net:

Package Downloads
SdJwt.Net.StatusList

SD-JWT Status List implementation for .NET, compliant with draft-ietf-oauth-status-list-13. Provides credential lifecycle management including revocation, suspension, and status verification for SD-JWT VCs. Ready for .NET 10.

SdJwt.Net.Vc

SD-JWT Verifiable Credentials implementation for .NET, compliant with draft-ietf-oauth-sd-jwt-vc-15. Extends SdJwt.Net with comprehensive VC functionality including validation, type safety, and digital credential support. Ready for .NET 10.

SdJwt.Net.Oid4Vci

A .NET library for OpenID for Verifiable Credential Issuance (OID4VCI) 1.0 protocol implementation. Provides transport-agnostic data models and utilities for SD-JWT integration with comprehensive flow support. Ready for .NET 10.

SdJwt.Net.OidFederation

A .NET library for OpenID Federation 1.0 specification implementation. Provides trust chain validation, entity configuration management, and federation metadata support for SD-JWT ecosystems. Ready for .NET 10.

SdJwt.Net.Oid4Vp

A .NET library for OpenID for Verifiable Presentations (OID4VP) 1.0 protocol implementation. Provides transport-agnostic data models and utilities for verifying SD-JWT presentations with Presentation Exchange v2.0.0 support. Ready for .NET 10.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 41 3/13/2026
1.0.1 429 3/1/2026
1.0.0 337 2/28/2026

Version 1.0.0: RFC 9901 compliant SD-JWT implementation with
                       JWS JSON Serialization, enhanced security features, algorithm validation,
                       and multi-platform support. Ready for .NET 10.