pyjwkest: JSON Web Key (JWK) / Token (JWT) library
pyjwkest is a Python implementation of JSON Web Token (JWT), JSON Web Encryption (JWE), JSON Web Signature (JWS), and JSON Web Key (JWK) specifications. Currently at version 1.4.4, the library is in maintenance mode, meaning only security-critical bugs will be fixed, and no new features are planned. Releases are infrequent, focusing on stability and security.
Warnings
- breaking The underlying cryptographic library changed from `pycrypto` to `pycryptodomex` in versions 1.1.0 and 1.2.0. Direct imports or assumptions about the crypto backend from `pycrypto` will break.
- gotcha The `pyjwkest` library is officially in maintenance mode. This means only security-critical bugs will be addressed, and no new features or significant development are planned. Users should be aware of this for long-term project planning.
- deprecated Older versions of pyjwkest (before 1.4.4) may use deprecated `array.tostring` and `array.tobytes` APIs, which can lead to warnings or errors in newer Python environments.
- gotcha Deserialization of EC (Elliptic Curve) keys can be problematic in older versions, specifically if the keys use unsupported curves or malformed formats, leading to exceptions.
- breaking Version 1.3.2 fixed a major problem in symmetric key construction. Code relying on symmetric keys from versions before 1.3.2 might generate incorrect or insecure keys.
Install
-
pip install pyjwkest
Imports
- JWT
from jwkest.jwt import JWT
- JWS
from jwkest.jws import JWS
- JWE
from jwkest.jwe import JWE
- RSAKey
from jwkest.jwk import RSAKey
- ECKey
from jwkest.jwk import ECKey
- symKey
from jwkest.jwk import symKey
- generate_key
from jwkest.jwk import generate_key
Quickstart
import json
from jwkest.jwk import RSAKey, generate_key
from jwkest.jws import JWS
# 1. Generate an RSA key pair for signing and verification
print("Generating RSA key pair...")
rsa_key = generate_key(alg='RS256', size=2048)
private_jwk = rsa_key.export_private()
public_jwk = rsa_key.export_public()
print("Private JWK (fragment):", {k: v for k, v in private_jwk.items() if k != 'd' and len(str(v)) < 50})
print("Public JWK (fragment):", {k: v for k, v in public_jwk.items() if len(str(v)) < 50})
# 2. Define JWT claims
claims = {
"iss": "example.com",
"aud": "client.example.org",
"sub": "user123",
"exp": 1893456000 # January 1, 2030
}
print("\nClaims to sign:", claims)
# 3. Create a JWS object and sign the claims
_jws_signer = JWS(json.dumps(claims))
signed_jwt = _jws_signer.sign(private_jwk)
print("\nSigned JWT:", signed_jwt)
# 4. Verify the JWT using the public key
print("\nVerifying JWT...")
_jws_verifier = JWS(signed_jwt)
try:
# Pass the public key for verification
verified_payload_str = _jws_verifier.verify(jwk=public_jwk)
verified_payload = json.loads(verified_payload_str)
print("Verification successful!")
print("Verified payload:", verified_payload)
except Exception as e:
print(f"Verification failed: {e}")