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
- Registered
Claims - Registered claim names from https://www.rfc-editor.org/rfc/rfc7519#section-4.1
- RsaPublic
Key - An RSA public key for JWT verification, supporting both PKCS#1 v1.5 and RSA-PSS signatures.
- Secret
Key - A symmetric secret key used with the
BLAKE3,HS256,HS384, andHS512algorithms. - Signature
- System
Clock - A
Clockbacked bystd::time::SystemTime. - Verify
Options
Enums§
- Algorithm
- The algorithms supported for signing / verifying JWTs
- EcCurve
- Error
- JwkCrypto
- Key
- A JWK decoded into a concrete cryptographic key.
- KeyUse
- OkpCurve
- Token
Type