JOSE implementation in Python providing JWT, JWS, JWE, and JWK functionality with multiple cryptographic backends.
75
Core algorithm constants, configuration options, and utility values used throughout the JOSE implementations. This module provides standardized algorithm identifiers and collections for easy reference and validation.
The ALGORITHMS object provides constants for all supported cryptographic algorithms across JWT, JWS, and JWE operations.
# HMAC Algorithms (Symmetric)
ALGORITHMS.HS256 = "HS256" # HMAC using SHA-256 hash
ALGORITHMS.HS384 = "HS384" # HMAC using SHA-384 hash
ALGORITHMS.HS512 = "HS512" # HMAC using SHA-512 hash
# RSA Algorithms (Asymmetric)
ALGORITHMS.RS256 = "RS256" # RSA PKCS#1 v1.5 using SHA-256
ALGORITHMS.RS384 = "RS384" # RSA PKCS#1 v1.5 using SHA-384
ALGORITHMS.RS512 = "RS512" # RSA PKCS#1 v1.5 using SHA-512
# ECDSA Algorithms (Asymmetric)
ALGORITHMS.ES256 = "ES256" # ECDSA using P-256 curve and SHA-256
ALGORITHMS.ES384 = "ES384" # ECDSA using P-384 curve and SHA-384
ALGORITHMS.ES512 = "ES512" # ECDSA using P-521 curve and SHA-512
# Special Algorithm
ALGORITHMS.NONE = "none" # No signature algorithm (use with caution)Usage Examples:
from jose.constants import ALGORITHMS
from jose import jwt, jws
# Use constants for consistency and avoiding typos
token = jwt.encode({'user': 'john'}, 'secret', algorithm=ALGORITHMS.HS256)
claims = jwt.decode(token, 'secret', algorithms=[ALGORITHMS.HS256])
# RSA signing
rsa_token = jwt.encode({'user': 'jane'}, rsa_private_key, algorithm=ALGORITHMS.RS256)
# ECDSA signing
ec_token = jwt.encode({'user': 'bob'}, ec_private_key, algorithm=ALGORITHMS.ES256)
# Multiple algorithm support
claims = jwt.decode(token, key, algorithms=[ALGORITHMS.HS256, ALGORITHMS.HS384, ALGORITHMS.HS512])# AES-GCM Algorithms (Authenticated Encryption)
ALGORITHMS.A128GCM = "A128GCM" # AES-128-GCM
ALGORITHMS.A192GCM = "A192GCM" # AES-192-GCM
ALGORITHMS.A256GCM = "A256GCM" # AES-256-GCM (Recommended)
# AES-CBC + HMAC Algorithms (Legacy Compatibility)
ALGORITHMS.A128CBC_HS256 = "A128CBC-HS256" # AES-128-CBC + HMAC-SHA-256
ALGORITHMS.A192CBC_HS384 = "A192CBC-HS384" # AES-192-CBC + HMAC-SHA-384
ALGORITHMS.A256CBC_HS512 = "A256CBC-HS512" # AES-256-CBC + HMAC-SHA-512
# AES-CBC Pseudo Algorithms (Internal Use)
ALGORITHMS.A128CBC = "A128CBC" # AES-128-CBC
ALGORITHMS.A192CBC = "A192CBC" # AES-192-CBC
ALGORITHMS.A256CBC = "A256CBC" # AES-256-CBCUsage Examples:
from jose import jwe
from jose.constants import ALGORITHMS
# Modern authenticated encryption (recommended)
encrypted = jwe.encrypt(plaintext, key, ALGORITHMS.A256GCM, ALGORITHMS.DIR)
# Legacy compatibility modes
encrypted = jwe.encrypt(plaintext, key, ALGORITHMS.A256CBC_HS512, ALGORITHMS.DIR)
# Different key lengths
encrypted = jwe.encrypt(plaintext, key_128, ALGORITHMS.A128GCM, ALGORITHMS.DIR)
encrypted = jwe.encrypt(plaintext, key_192, ALGORITHMS.A192GCM, ALGORITHMS.DIR)
encrypted = jwe.encrypt(plaintext, key_256, ALGORITHMS.A256GCM, ALGORITHMS.DIR)# Direct Encryption
ALGORITHMS.DIR = "dir" # Direct use of Content Encryption Key
# RSA Key Wrapping
ALGORITHMS.RSA1_5 = "RSA1_5" # RSA PKCS#1 v1.5 (deprecated)
ALGORITHMS.RSA_OAEP = "RSA-OAEP" # RSA OAEP with SHA-1 and MGF1
ALGORITHMS.RSA_OAEP_256 = "RSA-OAEP-256" # RSA OAEP with SHA-256 and MGF1 (recommended)
# AES Key Wrapping
ALGORITHMS.A128KW = "A128KW" # AES-128 Key Wrap
ALGORITHMS.A192KW = "A192KW" # AES-192 Key Wrap
ALGORITHMS.A256KW = "A256KW" # AES-256 Key Wrap
# Elliptic Curve Diffie-Hellman
ALGORITHMS.ECDH_ES = "ECDH-ES" # ECDH Ephemeral Static
ALGORITHMS.ECDH_ES_A128KW = "ECDH-ES+A128KW" # ECDH-ES + AES-128 Key Wrap
ALGORITHMS.ECDH_ES_A192KW = "ECDH-ES+A192KW" # ECDH-ES + AES-192 Key Wrap
ALGORITHMS.ECDH_ES_A256KW = "ECDH-ES+A256KW" # ECDH-ES + AES-256 Key Wrap
# AES-GCM Key Wrapping
ALGORITHMS.A128GCMKW = "A128GCMKW" # AES-128-GCM Key Wrap
ALGORITHMS.A192GCMKW = "A192GCMKW" # AES-192-GCM Key Wrap
ALGORITHMS.A256GCMKW = "A256GCMKW" # AES-256-GCM Key Wrap
# Password-Based Key Wrapping
ALGORITHMS.PBES2_HS256_A128KW = "PBES2-HS256+A128KW" # PBES2-HS256 + AES-128 Key Wrap
ALGORITHMS.PBES2_HS384_A192KW = "PBES2-HS384+A192KW" # PBES2-HS384 + AES-192 Key Wrap
ALGORITHMS.PBES2_HS512_A256KW = "PBES2-HS512+A256KW" # PBES2-HS512 + AES-256 Key WrapUsage Examples:
from jose import jwe
from jose.constants import ALGORITHMS
# Direct encryption (key = CEK)
encrypted = jwe.encrypt(plaintext, direct_key, ALGORITHMS.A256GCM, ALGORITHMS.DIR)
# RSA key wrapping (recommended)
encrypted = jwe.encrypt(plaintext, rsa_public_key, ALGORITHMS.A256GCM, ALGORITHMS.RSA_OAEP_256)
# AES key wrapping
encrypted = jwe.encrypt(plaintext, aes_kek, ALGORITHMS.A256GCM, ALGORITHMS.A256KW)
# Legacy RSA (not recommended)
encrypted = jwe.encrypt(plaintext, rsa_public_key, ALGORITHMS.A256GCM, ALGORITHMS.RSA1_5)Pre-defined sets of related algorithms for validation and filtering.
# Signature Algorithm Collections
ALGORITHMS.HMAC = {HS256, HS384, HS512} # All HMAC algorithms
ALGORITHMS.RSA_DS = {RS256, RS384, RS512} # RSA digital signature algorithms
ALGORITHMS.EC_DS = {ES256, ES384, ES512} # EC digital signature algorithms
ALGORITHMS.RSA = RSA_DS.union(RSA_KW) # All RSA algorithms
ALGORITHMS.EC = EC_DS.union(EC_KW) # All EC algorithms
# Encryption Algorithm Collections
ALGORITHMS.AES_ENC = {A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
ALGORITHMS.AES_KW = {A128KW, A192KW, A256KW} # AES key wrapping algorithms
ALGORITHMS.RSA_KW = {RSA1_5, RSA_OAEP, RSA_OAEP_256} # RSA key wrapping algorithms
ALGORITHMS.GCM = {A128GCM, A192GCM, A256GCM} # GCM algorithms
ALGORITHMS.HMAC_AUTH_TAG = {A128CBC_HS256, A192CBC_HS384, A256CBC_HS512} # HMAC auth tag algorithms
# Additional Collections
ALGORITHMS.AES_PSEUDO = {A128CBC, A192CBC, A256CBC, A128GCM, A192GCM, A256GCM} # AES pseudo algorithms
ALGORITHMS.AES_JWE_ENC = {A128CBC_HS256, A192CBC_HS384, A256CBC_HS512, A128GCM, A192GCM, A256GCM} # JWE encryption algorithms
ALGORITHMS.AES = AES_ENC.union(AES_KW) # All AES algorithms
ALGORITHMS.AEC_GCM_KW = {A128GCMKW, A192GCMKW, A256GCMKW} # AES-GCM key wrapping algorithms
ALGORITHMS.PBES2_KW = {PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW} # PBES2 key wrapping algorithms
ALGORITHMS.EC_KW = {ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW} # EC key wrapping algorithms
# Support Collections
ALGORITHMS.SUPPORTED = set # All algorithms supported by current backend
ALGORITHMS.ALL = set # All defined algorithms (including unsupported)
ALGORITHMS.KEYS = {} # Dictionary for registered key classesUsage Examples:
from jose.constants import ALGORITHMS
from jose import jwt
# Check if algorithm is HMAC
if algorithm in ALGORITHMS.HMAC:
# Use symmetric key
token = jwt.encode(claims, symmetric_key, algorithm=algorithm)
# Check if algorithm is RSA
elif algorithm in ALGORITHMS.RSA_DS:
# Use RSA private key
token = jwt.encode(claims, rsa_private_key, algorithm=algorithm)
# Validate algorithm support
if algorithm not in ALGORITHMS.SUPPORTED:
raise ValueError(f"Algorithm {algorithm} not supported")
# Accept only secure algorithms
secure_algorithms = ALGORITHMS.HMAC.union(ALGORITHMS.RSA_DS).union(ALGORITHMS.EC_DS)
claims = jwt.decode(token, key, algorithms=list(secure_algorithms))Mapping from algorithms to their corresponding hash functions.
ALGORITHMS.HASHES = {
HS256: hashlib.sha256, # SHA-256 for HS256
HS384: hashlib.sha384, # SHA-384 for HS384
HS512: hashlib.sha512, # SHA-512 for HS512
RS256: hashlib.sha256, # SHA-256 for RS256
RS384: hashlib.sha384, # SHA-384 for RS384
RS512: hashlib.sha512, # SHA-512 for RS512
ES256: hashlib.sha256, # SHA-256 for ES256
ES384: hashlib.sha384, # SHA-384 for ES384
ES512: hashlib.sha512 # SHA-512 for ES512
}Usage Examples:
from jose.constants import ALGORITHMS
import hashlib
# Get hash function for algorithm
hash_func = ALGORITHMS.HASHES.get(ALGORITHMS.HS256) # returns hashlib.sha256
if hash_func:
digest = hash_func(b'message').digest()
# Check hash function availability
for alg, hash_func in ALGORITHMS.HASHES.items():
print(f"{alg}: {hash_func.__name__}")Constants for compression algorithms used in JWE operations.
# Compression Constants
ZIPS.DEF = "DEF" # DEFLATE compression algorithm
ZIPS.NONE = None # No compression
# Supported Compression
ZIPS.SUPPORTED = {DEF, NONE} # Supported compression algorithmsUsage Examples:
from jose import jwe
from jose.constants import ALGORITHMS, ZIPS
# With DEFLATE compression
encrypted = jwe.encrypt(
large_plaintext,
key,
encryption=ALGORITHMS.A256GCM,
algorithm=ALGORITHMS.DIR,
zip=ZIPS.DEF
)
# Without compression (default)
encrypted = jwe.encrypt(
plaintext,
key,
encryption=ALGORITHMS.A256GCM,
algorithm=ALGORITHMS.DIR,
zip=ZIPS.NONE # or omit zip parameter
)
# Validate compression algorithm
if compression_alg in ZIPS.SUPPORTED:
encrypted = jwe.encrypt(plaintext, key, zip=compression_alg)Configuration constants for operational limits.
JWE_SIZE_LIMIT = 250 * 1024 # 250 KB maximum JWE payload sizeUsage Examples:
from jose.constants import JWE_SIZE_LIMIT
# Check payload size before encryption
if len(plaintext) > JWE_SIZE_LIMIT:
raise ValueError(f"Payload too large: {len(plaintext)} bytes > {JWE_SIZE_LIMIT} bytes")
encrypted = jwe.encrypt(plaintext, key)Digital Signatures:
ALGORITHMS.HS256 for symmetric keys, ALGORITHMS.RS256 or ALGORITHMS.ES256 for asymmetricContent Encryption:
ALGORITHMS.A256GCM for content encryptionALGORITHMS.RSA_OAEP_256 for RSA key wrapping, ALGORITHMS.DIR for pre-shared keys# Recommended combinations for new applications
from jose.constants import ALGORITHMS
# High-security symmetric
jwt_token = jwt.encode(claims, secret, algorithm=ALGORITHMS.HS256)
# High-security asymmetric
jwt_token = jwt.encode(claims, rsa_private_key, algorithm=ALGORITHMS.RS256)
# Modern asymmetric (smaller signatures)
jwt_token = jwt.encode(claims, ec_private_key, algorithm=ALGORITHMS.ES256)
# Secure encryption
encrypted = jwe.encrypt(
plaintext,
rsa_public_key,
encryption=ALGORITHMS.A256GCM,
algorithm=ALGORITHMS.RSA_OAEP_256
)For compatibility with older systems that may not support modern algorithms:
# Legacy JWT compatibility
legacy_algorithms = [
ALGORITHMS.HS256, ALGORITHMS.HS384, ALGORITHMS.HS512, # HMAC
ALGORITHMS.RS256, ALGORITHMS.RS384, ALGORITHMS.RS512 # RSA
]
# Legacy JWE compatibility
legacy_encrypted = jwe.encrypt(
plaintext,
key,
encryption=ALGORITHMS.A256CBC_HS512, # CBC + HMAC instead of GCM
algorithm=ALGORITHMS.DIR
)Symmetric Algorithms (HMAC):
HS256: 128-bit security levelHS384: 192-bit security levelHS512: 256-bit security levelAsymmetric Algorithms:
RS256/ES256: ~128-bit security levelRS384/ES384: ~192-bit security levelRS512/ES512: ~256-bit security levelEncryption Algorithms:
A128GCM: 128-bit security levelA192GCM: 192-bit security levelA256GCM: 256-bit security level# Performance ranking (fastest to slowest)
# 1. HMAC algorithms (HS256, HS384, HS512) - Symmetric, very fast
# 2. ECDSA algorithms (ES256, ES384, ES512) - Asymmetric, fast
# 3. RSA algorithms (RS256, RS384, RS512) - Asymmetric, slower
# Signature size ranking (smallest to largest)
# 1. ECDSA algorithms - Small signatures (~64-132 bytes)
# 2. HMAC algorithms - Medium signatures (~32-64 bytes)
# 3. RSA algorithms - Large signatures (~256-512 bytes)from jose.constants import ALGORITHMS
def validate_algorithm(algorithm, allowed_types='all'):
"""Validate algorithm against allowed types."""
if allowed_types == 'symmetric' and algorithm not in ALGORITHMS.HMAC:
raise ValueError("Only symmetric algorithms allowed")
elif allowed_types == 'asymmetric' and algorithm in ALGORITHMS.HMAC:
raise ValueError("Only asymmetric algorithms allowed")
elif algorithm not in ALGORITHMS.SUPPORTED:
raise ValueError(f"Algorithm {algorithm} not supported")
return True
# Usage
validate_algorithm(ALGORITHMS.HS256, 'symmetric') # OK
validate_algorithm(ALGORITHMS.RS256, 'asymmetric') # OKfrom jose.constants import ALGORITHMS
def select_algorithm(key_type, security_level=256):
"""Select appropriate algorithm based on key type and security level."""
if key_type == 'symmetric':
if security_level >= 256:
return ALGORITHMS.HS512
elif security_level >= 192:
return ALGORITHMS.HS384
else:
return ALGORITHMS.HS256
elif key_type == 'rsa':
if security_level >= 256:
return ALGORITHMS.RS512
elif security_level >= 192:
return ALGORITHMS.RS384
else:
return ALGORITHMS.RS256
elif key_type == 'ec':
if security_level >= 256:
return ALGORITHMS.ES512
elif security_level >= 192:
return ALGORITHMS.ES384
else:
return ALGORITHMS.ES256
else:
raise ValueError(f"Unknown key type: {key_type}")
# Usage
algorithm = select_algorithm('symmetric', 256) # Returns HS512
algorithm = select_algorithm('ec', 128) # Returns ES256ALGORITHMS constants instead of string literalsALGORITHMS.SUPPORTEDInstall with Tessl CLI
npx tessl i tessl/pypi-python-jose