CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-jsonwebtoken--jjwt-api

JJWT API - JSON Web Token library API for Java and Android

Pending
Overview
Eval results
Files

security-jwk.mddocs/

Security and JWK Management

This document covers key management, JSON Web Key (JWK) support, and cryptographic algorithm interfaces in JJWT API.

Key Utilities - Keys

The Keys class provides utilities for key generation and secure key management.

public final class Keys {
    // HMAC Key Generation
    public static SecretKey hmacShaKeyFor(byte[] bytes);
    
    // Key Generation (deprecated but available)
    @Deprecated
    public static SecretKey secretKeyFor(SignatureAlgorithm alg);
    @Deprecated
    public static KeyPair keyPairFor(SignatureAlgorithm alg);
    
    // Password Creation
    public static Password password(char[] password);
    
    // Key Builders
    public static SecretKeyBuilder builder(SecretKey key);
    public static PrivateKeyBuilder builder(PrivateKey key);
}

Key Generation Examples

import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.Jwts;
import javax.crypto.SecretKey;

// Generate secure keys for different algorithms
SecretKey hs256Key = Keys.secretKeyFor(Jwts.SIG.HS256);
SecretKey hs384Key = Keys.secretKeyFor(Jwts.SIG.HS384);
SecretKey hs512Key = Keys.secretKeyFor(Jwts.SIG.HS512);

// Generate encryption keys
SecretKey aes128Key = Keys.secretKeyFor(Jwts.ENC.A128GCM);
SecretKey aes256Key = Keys.secretKeyFor(Jwts.ENC.A256GCM);

// Create key from existing bytes (must be appropriate length)
byte[] keyBytes = new byte[32]; // 256 bits for HS256
new SecureRandom().nextBytes(keyBytes);
SecretKey hmacKey = Keys.hmacShaKeyFor(keyBytes);

// Create password for PBES2 algorithms
char[] passwordChars = "mySecurePassword".toCharArray();
Password password = Keys.password(passwordChars);

JWK Utilities - Jwks

The Jwks class provides comprehensive JSON Web Key (JWK) support including creation, parsing, and management.

public final class Jwks {
    // JWK Factory Methods
    public static DynamicJwkBuilder<?, ?> builder();
    public static JwkParserBuilder parser();
    public static JwkSetBuilder set();
    public static JwkSetParserBuilder setParser();
    
    // JSON Conversion
    public static String json(PublicJwk<?> publicJwk);
    public static String UNSAFE_JSON(Jwk<?> jwk);
    
    // Standard Curves
    public static final class CRV {
        public static final Curve P256;
        public static final Curve P384;
        public static final Curve P521;
        public static final Curve Ed25519;
        public static final Curve Ed448;
        public static final Curve X25519;
        public static final Curve X448;
    }
    
    // Standard Hash Algorithms
    public static final class HASH {
        public static final HashAlgorithm SHA256;
        public static final HashAlgorithm SHA384;
        public static final HashAlgorithm SHA512;
        public static final HashAlgorithm SHA3_256;
        public static final HashAlgorithm SHA3_384;
        public static final HashAlgorithm SHA3_512;
    }
    
    // Standard Key Operations
    public static final class OP {
        public static final KeyOperation SIGN;
        public static final KeyOperation VERIFY;
        public static final KeyOperation ENCRYPT;
        public static final KeyOperation DECRYPT;
        public static final KeyOperation WRAP_KEY;
        public static final KeyOperation UNWRAP_KEY;
        public static final KeyOperation DERIVE_KEY;
        public static final KeyOperation DERIVE_BITS;
    }
}

JWK Interfaces

Base JWK Interface

public interface Jwk<K extends Key> extends Map<String, Object> {
    // Standard Parameters
    String getId();
    String getType();
    Set<KeyOperation> getOperations();
    String getAlgorithm();
    String getPublicKeyUse();
    
    // X.509 Certificate Chain
    Set<String> getX509CertificateChain();
    String getX509CertificateSha1Thumbprint();
    String getX509CertificateSha256Thumbprint();
    
    // Key Conversion
    K toKey();
    
    // Standard Parameter Names
    String TYPE = "kty";
    String PUBLIC_KEY_USE = "use";
    String KEY_OPERATIONS = "key_ops";
    String ALGORITHM = "alg";
    String KEY_ID = "kid";
    String X509_CERTIFICATE_CHAIN = "x5c";
    String X509_CERTIFICATE_SHA1_THUMBPRINT = "x5t";
    String X509_CERTIFICATE_SHA256_THUMBPRINT = "x5t#S256";
}

Specific JWK Types

// Symmetric Key JWK
public interface SecretJwk extends Jwk<SecretKey> {
    // Inherits all Jwk methods
}

// Public Key JWK Base
public interface PublicJwk<K extends PublicKey> extends Jwk<K> {
    // Inherits all Jwk methods
}

// Private Key JWK Base
public interface PrivateJwk<K extends PrivateKey, L extends PublicJwk<? extends PublicKey>, M extends KeyPair<? extends PublicKey, K>> extends Jwk<K> {
    L toPublicJwk();
    M toKeyPair();
}

// RSA JWKs
public interface RsaPublicJwk extends PublicJwk<RSAPublicKey>, AsymmetricJwk<RSAPublicKey, RSAPrivateKey> {
    // RSA-specific methods
}

public interface RsaPrivateJwk extends PrivateJwk<RSAPrivateKey, RsaPublicJwk, KeyPair<RSAPublicKey, RSAPrivateKey>>, AsymmetricJwk<RSAPublicKey, RSAPrivateKey> {
    // RSA private key specific methods
}

// EC JWKs
public interface EcPublicJwk extends PublicJwk<ECPublicKey>, AsymmetricJwk<ECPublicKey, ECPrivateKey> {
    Curve getCurve();
}

public interface EcPrivateJwk extends PrivateJwk<ECPrivateKey, EcPublicJwk, KeyPair<ECPublicKey, ECPrivateKey>>, AsymmetricJwk<ECPublicKey, ECPrivateKey> {
    Curve getCurve();
}

// Octet Key Pair JWKs (Ed25519, Ed448, X25519, X448)
public interface OctetPublicJwk<K extends PublicKey> extends PublicJwk<K> {
    Curve getCurve();
}

public interface OctetPrivateJwk<K extends PrivateKey, L extends OctetPublicJwk<? extends PublicKey>> extends PrivateJwk<K, L, KeyPair<? extends PublicKey, K>> {
    Curve getCurve();
}

JWK Builders

Dynamic JWK Builder

public interface DynamicJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBuilder<K, J> {
    // Auto-detects key type and provides appropriate builder
    DynamicJwkBuilder<K, J> key(K key);
}

Specific JWK Builders

// Secret JWK Builder
public interface SecretJwkBuilder extends JwkBuilder<SecretKey, SecretJwk> {
    SecretJwkBuilder key(SecretKey key);
}

// RSA JWK Builders
public interface RsaPublicJwkBuilder extends AsymmetricJwkBuilder<RSAPublicKey, RSAPrivateKey, RsaPublicJwk, RsaPublicJwkBuilder> {
    RsaPublicJwkBuilder key(RSAPublicKey key);
}

public interface RsaPrivateJwkBuilder extends PrivateJwkBuilder<RSAPrivateKey, RsaPublicJwk, KeyPair<RSAPublicKey, RSAPrivateKey>, RsaPrivateJwk, RsaPrivateJwkBuilder> {
    RsaPrivateJwkBuilder key(RSAPrivateKey key);
}

// EC JWK Builders  
public interface EcPublicJwkBuilder extends AsymmetricJwkBuilder<ECPublicKey, ECPrivateKey, EcPublicJwk, EcPublicJwkBuilder> {
    EcPublicJwkBuilder key(ECPublicKey key);
    EcPublicJwkBuilder curve(Curve curve);
}

public interface EcPrivateJwkBuilder extends PrivateJwkBuilder<ECPrivateKey, EcPublicJwk, KeyPair<ECPublicKey, ECPrivateKey>, EcPrivateJwk, EcPrivateJwkBuilder> {
    EcPrivateJwkBuilder key(ECPrivateKey key);
    EcPrivateJwkBuilder curve(Curve curve);
}

JWK Builder Usage Examples

import io.jsonwebtoken.security.Jwks;
import io.jsonwebtoken.security.RsaPrivateJwk;
import io.jsonwebtoken.security.EcPublicJwk;
import java.security.KeyPairGenerator;
import java.security.KeyPair;

// Generate RSA key pair
KeyPairGenerator rsaGenerator = KeyPairGenerator.getInstance("RSA");
rsaGenerator.initialize(2048);
KeyPair rsaKeyPair = rsaGenerator.generateKeyPair();

// Create RSA private JWK
RsaPrivateJwk rsaJwk = Jwks.builder()
    .key(rsaKeyPair.getPrivate())
    .keyId("rsa-key-1")
    .algorithm("RS256")
    .operations(Jwks.OP.SIGN)
    .build();

// Create EC public JWK
KeyPairGenerator ecGenerator = KeyPairGenerator.getInstance("EC");
ecGenerator.initialize(256);
KeyPair ecKeyPair = ecGenerator.generateKeyPair();

EcPublicJwk ecJwk = Jwks.builder()
    .key((ECPublicKey) ecKeyPair.getPublic())
    .keyId("ec-key-1")
    .curve(Jwks.CRV.P256)
    .operations(Jwks.OP.VERIFY)
    .build();

// Convert JWK to JSON (safe for public keys)
String rsaPublicJson = Jwks.json(rsaJwk.toPublicJwk());
String ecPublicJson = Jwks.json(ecJwk);

// Convert to Java Key
RSAPrivateKey rsaPrivateKey = rsaJwk.toKey();
ECPublicKey ecPublicKey = ecJwk.toKey();

JWK Sets

JWK Set Interface

public interface JwkSet extends Map<String, Object> {
    Set<Jwk<?>> getKeys();
    
    // Standard Parameter Names
    String KEYS = "keys";
}

JWK Set Builder

public interface JwkSetBuilder extends Builder<JwkSet> {
    JwkSetBuilder add(Jwk<?> jwk);
    JwkSetBuilder add(Collection<? extends Jwk<?>> jwks);
    JwkSetBuilder keys(Collection<? extends Jwk<?>> jwks);
    JwkSet build();
}

JWK Set Usage Example

import io.jsonwebtoken.security.JwkSet;
import io.jsonwebtoken.security.Jwks;

// Create JWK Set with multiple keys
JwkSet jwkSet = Jwks.set()
    .add(rsaJwk.toPublicJwk())
    .add(ecJwk)
    .build();

// Convert to JSON
String jwkSetJson = Jwks.json(jwkSet);

// Access keys
Set<Jwk<?>> keys = jwkSet.getKeys();
for (Jwk<?> jwk : keys) {
    System.out.println("Key ID: " + jwk.getId());
    System.out.println("Key Type: " + jwk.getType());
}

JWK Parsing

JWK Parser Builder

public interface JwkParserBuilder extends Builder<JwkParser> {
    JwkParserBuilder provider(Provider provider);
    JwkParserBuilder deserializer(Deserializer<Map<String, ?>> deserializer);
    JwkParser build();
}

JWK Set Parser Builder

public interface JwkSetParserBuilder extends Builder<JwkSetParser> {
    JwkSetParserBuilder provider(Provider provider);
    JwkSetParserBuilder deserializer(Deserializer<Map<String, ?>> deserializer);
    JwkSetParser build();
}

JWK Parsing Examples

import io.jsonwebtoken.security.Jwks;
import io.jsonwebtoken.security.Jwk;
import io.jsonwebtoken.security.JwkSet;

// Parse single JWK from JSON
String jwkJson = "{ \"kty\": \"RSA\", \"kid\": \"key1\", ... }";

Jwk<?> parsedJwk = Jwks.parser()
    .build()
    .parse(jwkJson);

// Parse JWK Set from JSON
String jwkSetJson = "{ \"keys\": [ { \"kty\": \"RSA\", ... }, { \"kty\": \"EC\", ... } ] }";

JwkSet parsedJwkSet = Jwks.parser()
    .build()
    .parseSet(jwkSetJson);

// Access parsed keys
for (Jwk<?> jwk : parsedJwkSet.getKeys()) {
    System.out.println("Parsed key: " + jwk.getId());
}

Algorithm Interfaces

Signature Algorithms

public interface SignatureAlgorithm extends SecureDigestAlgorithm<PrivateKey, PublicKey>, KeyPairBuilderSupplier {
    // Digital signature algorithms (RS256, PS256, ES256, EdDSA, etc.)
}

public interface MacAlgorithm extends SecureDigestAlgorithm<SecretKey, SecretKey>, KeyBuilderSupplier<SecretKey> {
    // Message Authentication Code algorithms (HS256, HS384, HS512)
}

Encryption Algorithms

public interface AeadAlgorithm extends Identifiable {
    // Authenticated Encryption with Associated Data
    String getId();
    
    // AEAD Operations
    AeadResult encrypt(AeadRequest request) throws SecurityException;
    DecryptAeadRequest decrypt(DecryptAeadRequest request) throws SecurityException;
}

public interface KeyAlgorithm<E extends Key, D extends Key> extends Identifiable {
    // Key Management Algorithms
    String getId();
    
    // Key Management Operations  
    KeyResult getEncryptionKey(KeyRequest<E> request) throws SecurityException;
    SecretKey getDecryptionKey(DecryptionKeyRequest<D> request) throws SecurityException;
}

Algorithm Usage Examples

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.SignatureAlgorithm;
import io.jsonwebtoken.security.MacAlgorithm;

// Use specific algorithms
SignatureAlgorithm rs256 = Jwts.SIG.RS256;
MacAlgorithm hs256 = Jwts.SIG.HS256;

// Generate appropriate keys for algorithms
RSAPrivateKey rsaKey = rs256.keyPair().build().getPrivate();
SecretKey macKey = hs256.key().build();

// Use in JWT operations
String rsaJwt = Jwts.builder()
    .subject("user")
    .signWith(rsaKey, rs256)
    .compact();

String macJwt = Jwts.builder()
    .subject("user")
    .signWith(macKey, hs256)
    .compact();

Security Exception Hierarchy

public class SecurityException extends JwtException {
    // Base security exception
}

public class KeyException extends SecurityException {
    // General key-related errors
}

public class InvalidKeyException extends KeyException {
    // Invalid key format or content
}

public class WeakKeyException extends KeyException {
    // Key strength insufficient for algorithm
}

public class UnsupportedKeyException extends KeyException {
    // Key type not supported for operation
}

public class MalformedKeyException extends KeyException {
    // Key format is malformed
}

public class MalformedKeySetException extends SecurityException {
    // JWK Set format is malformed
}

public class SignatureException extends SecurityException {
    // Signature operation failed
}

Advanced Security Features

Key Strength Validation

JJWT automatically validates key strength according to JWA specifications:

// These will throw WeakKeyException if keys are too short
SecretKey weakKey = Keys.hmacShaKeyFor(new byte[16]); // Only 128 bits for HS256
SecretKey strongKey = Keys.hmacShaKeyFor(new byte[32]); // 256 bits - OK

// Automatic validation during JWT creation
try {
    String jwt = Jwts.builder()
        .subject("user")
        .signWith(weakKey, Jwts.SIG.HS256) // May throw WeakKeyException
        .compact();
} catch (WeakKeyException e) {
    System.err.println("Key too weak: " + e.getMessage());
}

Curve Support

JJWT supports all standard elliptic curves:

// NIST P-curves
Curve p256 = Jwks.CRV.P256;  // secp256r1
Curve p384 = Jwks.CRV.P384;  // secp384r1  
Curve p521 = Jwks.CRV.P521;  // secp521r1

// Edwards curves
Curve ed25519 = Jwks.CRV.Ed25519;  // EdDSA signing
Curve ed448 = Jwks.CRV.Ed448;      // EdDSA signing

// Montgomery curves  
Curve x25519 = Jwks.CRV.X25519;    // ECDH key agreement
Curve x448 = Jwks.CRV.X448;        // ECDH key agreement

JCA Provider Support

All security operations support custom JCA Providers:

Provider customProvider = new CustomSecurityProvider();

// Use custom provider for key generation
SecretKey key = Keys.builder(existingKey)
    .provider(customProvider)
    .build();

// Use custom provider for JWT operations
String jwt = Jwts.builder()
    .provider(customProvider)
    .subject("user")
    .signWith(key)
    .compact();

// Use custom provider for parsing
JwtParser parser = Jwts.parser()
    .provider(customProvider)
    .verifyWith(key)
    .build();

Install with Tessl CLI

npx tessl i tessl/maven-io-jsonwebtoken--jjwt-api

docs

index.md

io-utilities.md

jwt-operations.md

security-jwk.md

types.md

tile.json