-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
575 additions
and
599 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,4 +169,8 @@ env | |
|
||
.DS_Store | ||
|
||
docs/source | ||
docs/source | ||
|
||
# VSCode | ||
# VSCode specific settings | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,150 @@ | ||
# SD-JWT Documentation | ||
# sd-jwt-python Fork with cryptojwt | ||
|
||
## Introduction | ||
This document explains how to create and verify a Self-Contained JWT (SD-JWT) using the EUDI Wallet IT Python library. It also covers how to validate proof of possession. | ||
|
||
## Creating an SD-JWT | ||
This module is a fork of [sd-jwt-python](https://github.com/openwallet-foundation-labs/sd-jwt-python) project. It has been adapted to use the [`cryptojwt`](https://github.com/IdentityPython/JWTConnect-Python-CryptoJWT) library as the core JWT implementation. | ||
|
||
### Step 1: Import Necessary Modules | ||
To get started, you need to import the necessary modules from the EUDI Wallet IT Python library. | ||
|
||
```python | ||
from pyeudiw.sd_jwt.issuer import SDJWTIssuer | ||
from pyeudiw.jwk import JWK | ||
from pyeudiw.sd_jwt.exceptions import UnknownCurveNistName | ||
from pyeudiw.sd_jwt.verifier import SDJWTVerifier | ||
from json import dumps, loads | ||
``` | ||
If you're familiar with the original `sd-jwt-python` library, this fork retains similar functionality with minimal API changes, if needed. | ||
|
||
### Step 2: Prepare User Claims | ||
Define the claims that you want to include in your SD-JWT. | ||
--- | ||
|
||
```python | ||
user_claims = { | ||
"iss": "issuer_identifier", # The identifier for the issuer | ||
"sub": "subject_identifier", # The identifier for the subject | ||
"exp": 1234567890, # Expiration time (in seconds) | ||
"iat": 1234567890, # Issued at time (in seconds) | ||
# Add other claims as needed | ||
} | ||
## Features | ||
|
||
- **SD-JWT Support**: Implements the Selective Disclosure JWT standard. | ||
- **`cryptojwt` Integration**: Leverages a mature and feature-rich library for JWT operations. | ||
- **Backward Compatibility**: Minimal changes required for existing users of `sd-jwt-python`. | ||
- **Improved Flexibility**: Extensible for custom SD-JWT use cases. | ||
|
||
--- | ||
|
||
# SD-JWT Library Usage Documentation | ||
|
||
## Introduction | ||
|
||
This library provides an implementation of the SD-JWT (Selective Disclosure for JWT) standard. This document explains how to create and verify a Selected-Disclosure JWT (SD-JWT) using the EUDI Wallet IT Python library. It also covers how to validate proof of possession enabling three key operations: | ||
1. **Issuer**: Generate an SD-JWT with selective disclosure capabilities. | ||
2. **Holder**: Select claims to disclose and create a presentation. | ||
3. **Verifier**: Validate the SD-JWT and verify the disclosed claims. | ||
|
||
### Requirements | ||
- Python version as configured in the CI of this project. | ||
- Install the library via `pip`: | ||
```bash | ||
pip install pyeudiw | ||
``` | ||
|
||
### Step 3: Create Keys | ||
Generate or load your JSON Web Keys (JWKs). | ||
- **Key Requirements**: | ||
- All keys must be in JWK (JSON Web Key) format, conforming to [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517). | ||
- You can use a library like `cryptojwt` to generate or manage JWKs. Example: | ||
|
||
```python | ||
issuer_key = JWK(key_type='RSA') # Example for RSA key | ||
holder_key = JWK(key_type='RSA') # Example for RSA key | ||
```bash | ||
from cryptojwt.jwk.ec import new_ec_key | ||
|
||
# Generate an EC key pair | ||
issuer_private_key = new_ec_key('P-256') | ||
|
||
# Serialize the keys | ||
issuer_keys = [issuer_private_key.serialize(private=True)] # List of private keys | ||
public_key = issuer_private_key.serialize() # Public key | ||
``` | ||
--- | ||
|
||
### Step 4: Issue SD-JWT | ||
Create an instance of `SDJWTIssuer` and generate the JWT. | ||
## 1. Issuer: Generating an SD-JWT | ||
|
||
```python | ||
sd_jwt_issuer = SDJWTIssuer( | ||
The Issuer creates an SD-JWT using the user's claims (`user_claims`) and a private key in JWK format to sign the token. | ||
|
||
### Example | ||
|
||
```bash | ||
from pyeudiw.sd_jwt.issuer import SDJWTIssuer | ||
|
||
# User claims | ||
user_claims = { | ||
"sub": "john_doe_42", | ||
"given_name": "John", | ||
"family_name": "Doe", | ||
"email": "[email protected]", | ||
} | ||
|
||
# Generate private keys | ||
issuer_private_key = new_ec_key('P-256') | ||
issuer_keys = [issuer_private_key.serialize(private=True)] # List of private JWKs | ||
holder_key = new_ec_key('P-256').serialize(private=True) # Holder private key (optional) | ||
|
||
# Create SD-JWT | ||
sdjwt_issuer = SDJWTIssuer( | ||
user_claims=user_claims, | ||
issuer_key=issuer_key, | ||
holder_key=holder_key, | ||
sign_alg='RS256', # Example signing algorithm | ||
issuer_keys=issuer_keys, # List of private JWKs | ||
holder_key=holder_key, # Holder key (optional) | ||
add_decoy_claims=True, # Add decoy claims for privacy | ||
serialization_format="compact" # Compact JWS format | ||
) | ||
|
||
sd_jwt = sd_jwt_issuer.serialize() # Get the serialized SD-JWT | ||
print("Serialized SD-JWT:", sd_jwt) | ||
# Output SD-JWT and disclosures | ||
print("SD-JWT Issuance:", sdjwt_issuer.sd_jwt_issuance) | ||
``` | ||
|
||
## Verifying an SD-JWT | ||
--- | ||
|
||
### Step 1: Prepare the JWT | ||
Receive the SD-JWT that you want to verify. | ||
## 2. Holder: Creating a Selective Disclosure Presentation | ||
|
||
```python | ||
received_sd_jwt = sd_jwt # The JWT you want to verify | ||
``` | ||
The Holder receives the SD-JWT from the Issuer and selects which claims to disclose to the Verifier. | ||
|
||
### Step 2: Create Verifier Instance | ||
Use the `SDJWTVerifier` to verify the JWT. | ||
### Example | ||
|
||
```python | ||
sd_jwt_verifier = SDJWTVerifier( | ||
received_sd_jwt, | ||
issuer_key=issuer_key, | ||
holder_key=holder_key, | ||
```bash | ||
from pyeudiw.sd_jwt.holder import SDJWTHolder | ||
|
||
# Claims to disclose | ||
holder_disclosed_claims = { | ||
"given_name": True, | ||
"family_name": True | ||
} | ||
|
||
# Initialize Holder | ||
sdjwt_holder = SDJWTHolder(sdjwt_issuer.sd_jwt_issuance) | ||
|
||
# Create presentation with selected claims | ||
sdjwt_holder.create_presentation( | ||
disclosed_claims=holder_disclosed_claims, | ||
nonce=None, # Optional: Used for key binding | ||
verifier=None, # Optional: Verifier identifier for key binding | ||
holder_key=holder_key # Optional: Holder private key for key binding | ||
) | ||
|
||
verified_claims = sd_jwt_verifier.verify() # Get the verified claims | ||
print("Verified Claims:", verified_claims) | ||
# Output the presentation | ||
print("SD-JWT Presentation:", sdjwt_holder.sd_jwt_presentation) | ||
``` | ||
|
||
## Proof of Possession | ||
## 3. Verifier: Verifying an SD-JWT | ||
|
||
The Verifier validates the SD-JWT and checks the disclosed claims. | ||
|
||
To verify proof of possession, ensure that the holder key matches the expected public key during verification. This process should be included in your verification logic. | ||
### Example | ||
|
||
```python | ||
if holder_key.verify(verified_claims): | ||
print("Proof of possession is valid.") | ||
else: | ||
print("Invalid proof of possession.") | ||
``` | ||
from pyeudiw.sd_jwt.verifier import SDJWTVerifier | ||
|
||
# Callback to retrieve Issuer's public key | ||
def get_issuer_public_key(issuer, header_parameters): | ||
# Return the public key(s) in JWK format | ||
return [issuer_private_key.serialize()] | ||
|
||
# Initialize Verifier | ||
sdjwt_verifier = SDJWTVerifier( | ||
sdjwt_presentation=sdjwt_holder.sd_jwt_presentation, | ||
cb_get_issuer_key=get_issuer_public_key | ||
) | ||
|
||
# Verify and retrieve payload | ||
verified_payload = sdjwt_verifier.get_verified_payload() | ||
|
||
# Verified claims | ||
print("Verified Claims:", verified_payload) | ||
``` | ||
|
||
|
||
--- | ||
|
||
**Note:** | ||
For more specific implementation details read more on [SD-JWT](../pyeudiw/sd_jwt/SD-JWT.md). | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.