JWK
TypedDicts¶
JWKCommon¶
Common JWK parameters shared across all key types.
from jam.jose import JWKCommon
key: JWKCommon = {
"kty": "RSA", # Required. Key type: RSA, EC, oct
"use": "sig", # Public key use: "sig" or "enc"
"key_ops": ["sign"], # Intended key operations
"alg": "RS256", # Intended algorithm
"kid": "key-id", # Unique key identifier
"x5u": "https://...", # X.509 URL
"x5c": "MIID...", # X.509 certificate chain (base64)
"x5t": "abc...", # X.509 SHA-1 thumbprint
"x5t_S256": "xyz...", # X.509 SHA-256 thumbprint
}
JWKRSA¶
RSA key parameters (extends JWKCommon).
from jam.jose import JWKRSA
# Public key
rsa_pub: JWKRSA = {
"kty": "RSA",
"n": "0vx7agoebGcQSuu...", # Modulus (base64url)
"e": "AQAB", # Exponent (base64url)
}
# Private key (requires all CRT parameters per RFC 7518)
rsa_priv: JWKRSA = {
"kty": "RSA",
"n": "...", "e": "AQAB",
"d": "...", # Private exponent
"p": "...", # First prime factor
"q": "...", # Second prime factor
"dp": "...", # d mod (p-1)
"dq": "...", # d mod (q-1)
"qi": "...", # q^(-1) mod p
}
RSA private key validation
When d is present, all CRT parameters (p, q, dp, dq, qi) are
required. Missing any of them raises JamJWKValidationError per RFC 7518
Section 6.3.2.
JWKEC¶
Elliptic curve key parameters (extends JWKCommon).
from jam.jose import JWKEC
ec_key: JWKEC = {
"kty": "EC",
"crv": "P-256", # Supported: P-256, P-384, P-521
"x": "f83OJ3D...", # X coordinate (base64url)
"y": "x_FEzRu...", # Y coordinate (base64url)
"d": "...", # Private key (optional, base64url)
}
JWKOct¶
Symmetric (octet sequence) key parameters (extends JWKCommon).
from jam.jose import JWKOct
oct_key: JWKOct = {
"kty": "oct",
"k": "c2VjcmV0LWtleS0zMi1ieXRlcy1sb25n", # Key value (base64url)
}
Standalone (module)¶
JWK - JSON Web Key¶
JWK represents a cryptographic key in JSON format.
Create from dict¶
Method: JWK.from_dict
Creates JWK from dictionary.
Args:
data:dict[str, Any]- JWK dict. Required fieldkty.
Returns:
JWK: Validated JWK instance.
Raises:
JamJWKValidationError- If JWK is invalid.
from jam.jose import JWK
# Symmetric key (oct)
oct_key = JWK.from_dict({
"kty": "oct",
"k": "GawgguFyGrWKav7AX4VKUg", # base64url encoded key
"kid": "my-signing-key"
})
# RSA key
rsa_key = JWK.from_dict({
"kty": "RSA",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbW...",
"e": "AQAB",
"kid": "rsa-key-1"
})
# EC key
ec_key = JWK.from_dict({
"kty": "EC",
"crv": "P-256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
"kid": "ec-key-1"
})
Validate¶
Static method: JWK.validate
Validates and creates JWK from dict.
Args:
data:dict[str, Any]- JWK dict.
Returns:
JWK: Validated instance.
jwk = JWK.validate({"kty": "oct", "k": "base64key"})
Properties¶
JWK has the following properties:
kty:str- Key Type. Possible values:RSA,EC,oct.alg:str | None- Algorithm. Specifies algorithm to use with the key.kid:str | None- Key ID. Unique key identifier.
jwk = JWK.from_dict({"kty": "oct", "k": "key", "kid": "key1"})
print(jwk.kty) # "oct"
print(jwk.alg) # None
print(jwk.kid) # "key1"
All JWK parameters are accessible via to_dict():
| Parameter | Type | Description |
|---|---|---|
kty |
str |
Key Type (RSA, EC, oct) |
use |
str |
Public key use (sig, enc) |
key_ops |
list[str] |
Intended key operations |
alg |
str |
Intended algorithm |
kid |
str |
Key ID |
x5u |
str |
X.509 URL |
x5c |
str |
X.509 certificate chain |
x5t |
str |
X.509 SHA-1 thumbprint |
x5t#S256 |
str |
X.509 SHA-256 thumbprint |
Sign data¶
Method: jwk.sign
Signs data using JWK.
Args:
data:bytes- Data to sign.alg:str | None = None- Signing algorithm. IfNone, usesalgfrom JWK or default for kty.
Returns:
str: JWS in Compact Serialization format.
Raises:
JamJWSVerificationError- If signing failed.
jwk = JWK.from_dict({"kty": "oct", "k": "your-secret-key-32-bytes-long"})
token = jwk.sign(b"data to sign", alg="HS256")
Verify token¶
Method: jwk.verify
Verifies JWS token using JWK.
Args:
token:str- JWS token.alg:str | None = None- Algorithm. IfNone, uses from token header.
Returns:
dict[str, Any]: Parsed data with keys header, payload.
Raises:
JamJWSVerificationError- If verification failed.
result = jwk.verify(token)
print(result["payload"])
>>> b'data to sign'
Convert to dict¶
Method: jwk.to_dict
Converts JWK back to dictionary.
Returns:
dict[str, Any]: JWK dict.
jwk_dict = jwk.to_dict()
print(jwk_dict)
>>> {'kty': 'oct', 'k': 'your-secret-key-32-bytes-long', 'kid': 'key1'}
JWKSet - Set of Keys¶
JWKSet represents a set of JWK keys.
Create from dict¶
Method: JWKSet.from_dict
Creates JWKSet from dictionary.
Args:
data:dict[str, Any]- JWKSet dict withkeyskey.
Returns:
JWKSet: Validated instance.
Raises:
JamJWKValidationError- If data is invalid.
from jam.jose import JWKSet
jwks = JWKSet.from_dict({
"keys": [
{"kty": "oct", "k": "key1", "kid": "1"},
{"kty": "oct", "k": "key2", "kid": "2"},
{"kty": "RSA", "n": "...", "e": "AQAB", "kid": "rsa-key"}
]
})
Get by kid¶
Method: jwks.get_by_kid
Gets JWK by Key ID.
Args:
kid:str- Key ID.
Returns:
dict[str, Any] | None: JWK dict or None if not found.
key = jwks.get_by_kid("1")
if key:
jwk = JWK.from_dict(key)
Get by kty¶
Method: jwks.get_by_kty
Gets all JWKs with specified Key Type.
Args:
kty:str- Key Type (RSA,EC,oct).
Returns:
list[dict[str, Any]]: List of JWK dicts.
symmetric_keys = jwks.get_by_kty("oct")
rsa_keys = jwks.get_by_kty("RSA")
Filter¶
Method: jwks.filter
Filters JWKs by criteria.
Args:
**criteria: Filter criteria (kty,use,alg,key_ops,kid).
Returns:
list[dict[str, Any]]: List of matching JWK dicts.
# Find keys by multiple criteria
keys = jwks.filter(kty="RSA", use="sig")
Convert to dict¶
Method: jwks.to_dict
Converts JWKSet to dictionary.
Returns:
dict[str, Any]: JWKSet dict.
jwks_dict = jwks.to_dict()
JWK Key Types¶
oct - Symmetric Key¶
Symmetric key for HMAC algorithms.
from jam.jose import JWK
# Create
jwk = JWK.from_dict({
"kty": "oct",
"k": "c2VjcmV0LWtleS0zMi1ieXRlcy1sb25n", # base64url encoded
"kid": "hmac-key"
})
# Use for HMAC
token = jwk.sign(b"data", alg="HS256")
result = jwk.verify(token)
RSA¶
Asymmetric RSA key for RSA and RSA-PSS algorithms.
from jam.jose import JWK
rsa_jwk = JWK.from_dict({
"kty": "RSA",
"n": "...",
"e": "AQAB",
"d": "...", # private key only if needed
"p": "...",
"q": "...",
"dp": "...",
"dq": "...",
"qi": "...",
"kid": "rsa-key"
})
# Sign
token = rsa_jwk.sign(b"data", alg="RS256")
result = rsa_jwk.verify(token)
EC - Elliptic Curve¶
Elliptic curve key for ECDSA algorithms.
from jam.jose import JWK
ec_jwk = JWK.from_dict({
"kty": "EC",
"crv": "P-256", # or P-384, P-521
"x": "...",
"y": "...",
"d": "...", # private key only if needed
"kid": "ec-key"
})
# Sign
token = ec_jwk.sign(b"data", alg="ES256")
result = ec_jwk.verify(token)
Key type-specific classes¶
Typed key classes are exported for static type checking:
from jam.jose import JWKRSA, JWKEC, JWKOct
# These are TypedDicts for type annotations
def process_rsa_key(key: JWKRSA) -> None:
...
def process_ec_key(key: JWKEC) -> None:
...
def process_symmetric_key(key: JWKOct) -> None:
...