Skip to main content

Crate jwt

Crate jwt 

Source
Expand description

Sign, parse, and verify JSON Web Tokens (JWT).

§Two-step verification flow

parse_header and parse_and_verify are separate so that you can inspect the header, especially the kid field (Key ID), before choosing which key to verify with. This is essential when the key must be looked up dynamically.

§no_std support

Disable default features (default-features = false) and provide your own Clock implementation for time-based claim verification (optional).

§Example

use jwt::*;
use crypto::curve25519::ed25519;

fn main() -> Result<(), Error> {
    // 1. Generate an Ed25519 secret key.
    let secret_key = ed25519::SecretKey::generate();

    // 2. Build the header.
    let header = Header {
        typ: TokenType::JWT,
        alg: Algorithm::EdDSA,
        kid: Some("my-key-id".into()),
        cty: None,
        jku: None,
        x5u: None,
        x5c: None,
        x5t: None,
        x5t_s256: None,
    };

    // 3. Define the claims and sign.
    let claims = serde_json::json!({ "sub": "user123", "exp": 9999999999_u64 });
    let token = sign(&secret_key, &header, &claims)?;

    // 4. Extract the public key for verification.
    let public_key = secret_key.public_key();

    // 5. Parse only the header first (e.g., to read `kid` for key lookup).
    let parsed_header = parse_header(&token)?;
    assert_eq!(parsed_header.kid.as_deref(), Some("my-key-id"));

    // 6. Now verify and deserialize the claims.
    let opts = VerifyOptions {
        allowed_time_drift: core::time::Duration::from_secs(60),
        exp: true,
        nbf: false,
        aud: None,
        iss: None,
        clock: Some(&jwt::SYSTEM_CLOCK),
    };
    let claims: serde_json::Value =
        parse_and_verify(&public_key, &parsed_header, &token, &opts)?;
    assert_eq!(claims["sub"], "user123");

    Ok(())
}

§JSON Web Key (JWK) import and export

Keys can be exported to and imported from JSON Web Keys (JWK) for publishing or later re-use. Every supported key type implements From<&KeyType> for Jwk, and the reverse conversion is available through TryFrom<&Jwk>. Use it when the key is only known at runtime, for example after fetching a JWKS document. P-256, P-384 and P-521 public keys are all supported.

use jwt::*;
use crypto::p256;

fn main() -> Result<(), Error> {
    // Generate a P-256 key pair.
    let secret_key = p256::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
    let public_key = secret_key.public_key();

    // Convert to a JWK (e.g. for publishing in a JWKS endpoint).
    let jwk = Jwk::from(&public_key);
    assert_eq!(jwk.algorithm, Algorithm::ES256);

    // Parse the JWK back into a key (e.g. from a JWKS response).
    let key = p256::PublicKey::try_from(&jwk)?;

    let header = Header { typ: TokenType::JWT, alg: Algorithm::ES256, ..Default::default() };
    let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
    let parsed_header = parse_header(&token)?;
    let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;

    Ok(())
}

When the key type is not known ahead of time (for example a JWKS document that may contain several kinds of keys), use the Key enum. It inspects the JWK’s kty and crv and selects the matching concrete key, preferring the secret variant when both halves are present. Key implements both Signer and Verifier, so it can be passed straight to sign or parse_and_verify:

use jwt::*;
use crypto::curve25519::ed25519;

fn main() -> Result<(), Error> {
    let secret_key = ed25519::SecretKey::generate();

    // A JWKS entry whose key type is only known at runtime.
    let jwk = Jwk::from(&secret_key.public_key());
    let key = Key::try_from(&jwk)?;
    assert!(matches!(key, Key::Ed25519Public(_)));

    let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
    let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
    let parsed_header = parse_header(&token)?;
    let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;

    Ok(())
}

When a JWK derived from a secret key is decoded, the secret variant is preferred, so the same Key can be used for signing:

use jwt::*;
use crypto::curve25519::ed25519;

fn main() -> Result<(), Error> {
    let secret_key = ed25519::SecretKey::generate();
    let jwk = Jwk::from(&secret_key);
    let key = Key::try_from(&jwk)?;
    assert!(matches!(key, Key::Ed25519Secret(_)));

    let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
    let token = sign(&key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
    let parsed_header = parse_header(&token)?;
    let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;

    Ok(())
}

Structs§

Header
Jwk
a JSON Web Key https://www.rfc-editor.org/rfc/rfc7517 https://www.rfc-editor.org/rfc/rfc8037 https://www.ietf.org/archive/id/draft-ietf-jose-pqc-02.html Note: Jwk are not validated during deserialization
Jwks
RegisteredClaims
Registered claim names from https://www.rfc-editor.org/rfc/rfc7519#section-4.1
RsaPublicKey
An RSA public key for JWT verification, supporting both PKCS#1 v1.5 and RSA-PSS signatures.
SecretKey
A symmetric secret key used with the BLAKE3, HS256, HS384, and HS512 algorithms.
Signature
SystemClock
A Clock backed by std::time::SystemTime.
VerifyOptions

Enums§

Algorithm
The algorithms supported for signing / verifying JWTs
EcCurve
Error
JwkCrypto
Key
A JWK decoded into a concrete cryptographic key.
KeyUse
OkpCurve
TokenType

Statics§

SYSTEM_CLOCK

Traits§

Clock
A wall clock used to check tokens expiration.
Signer
Verifier

Functions§

parse_and_verify
parse_header
sign