CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-jose

JOSE implementation in Python providing JWT, JWS, JWE, and JWK functionality with multiple cryptographic backends.

75

1.44x
Overview
Eval results
Files

constants-algorithms.mddocs/

Constants and Algorithms

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.

Capabilities

Algorithm Constants

The ALGORITHMS object provides constants for all supported cryptographic algorithms across JWT, JWS, and JWE operations.

Digital Signature Algorithms

# 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])

Content Encryption Algorithms

# 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-CBC

Usage 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)

Key Management Algorithms

# 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 Wrap

Usage 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)

Algorithm Collections

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 classes

Usage 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))

Hash Function Mapping

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__}")

Compression Algorithms

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 algorithms

Usage 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)

Size Limits

Configuration constants for operational limits.

JWE_SIZE_LIMIT = 250 * 1024  # 250 KB maximum JWE payload size

Usage 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)

Algorithm Recommendations

For New Applications

Digital Signatures:

  • JWT/JWS: Use ALGORITHMS.HS256 for symmetric keys, ALGORITHMS.RS256 or ALGORITHMS.ES256 for asymmetric
  • Performance: HMAC algorithms are fastest
  • Security: ES256 provides smaller signatures than RS256

Content Encryption:

  • JWE: Use ALGORITHMS.A256GCM for content encryption
  • Key Management: Use ALGORITHMS.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
)

Legacy Compatibility

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
)

Algorithm Security Properties

Security Levels

Symmetric Algorithms (HMAC):

  • HS256: 128-bit security level
  • HS384: 192-bit security level
  • HS512: 256-bit security level

Asymmetric Algorithms:

  • RS256/ES256: ~128-bit security level
  • RS384/ES384: ~192-bit security level
  • RS512/ES512: ~256-bit security level

Encryption Algorithms:

  • A128GCM: 128-bit security level
  • A192GCM: 192-bit security level
  • A256GCM: 256-bit security level

Performance Characteristics

# 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)

Usage Patterns

Algorithm Validation

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')  # OK

Dynamic Algorithm Selection

from 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 ES256

Best Practices

  1. Use Constants: Always use ALGORITHMS constants instead of string literals
  2. Algorithm Validation: Validate algorithms against ALGORITHMS.SUPPORTED
  3. Security Requirements: Choose algorithms based on your security requirements
  4. Performance Needs: Consider performance implications of algorithm choice
  5. Future-Proofing: Design systems to support algorithm upgrades
  6. Legacy Support: Maintain compatibility while encouraging modern algorithms
  7. Key Sizes: Ensure key sizes match algorithm requirements
  8. Regular Updates: Stay informed about algorithm deprecations and recommendations

Install with Tessl CLI

npx tessl i tessl/pypi-python-jose

docs

constants-algorithms.md

index.md

jwe-operations.md

jwk-management.md

jws-operations.md

jwt-operations.md

tile.json