JOSE Protocol Implementation in Python

2.2.0 · active · verified Sat Apr 11

josepy is a Python library that implements the JOSE (JSON Object Signing and Encryption) protocol, providing cryptographic primitives for creating and verifying JWS (JSON Web Signatures) and JWE (JSON Web Encryption) messages. It serves as a foundational cryptography component for projects like Certbot. The current version is 2.2.0, with releases typically aligned with Certbot updates or critical security fixes for its dependencies.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to generate an RSA key (or load an existing one), sign a JWS message with it, serialize the JWS, and then verify it using the corresponding public key. Remember to handle private keys securely in production environments.

import os
from josepy import jwa, jws
from josepy.jwk import JWK

# 1. Generate or load a private key for signing
# In a production environment, load keys securely (e.g., from environment variables, KMS, or disk).
key_pem = os.environ.get('JOSEPY_PRIVATE_PRIVATE_KEY_PEM', None)
if key_pem:
    private_key = JWK.load(key_pem.encode('utf-8'))
else:
    # Generate a new RSA key for demonstration purposes
    private_key = jwa.RS256.create().key
    print("Generated a new RSA private key for demonstration. In production, load securely.")

# 2. Define the payload and protected header
payload = b"Hello, josepy! This is a signed message."
protected_header = jws.Protected({"alg": "RS256", "jwk": private_key.public_key.json_serializable})

# 3. Sign the message
signer = jwa.RS256.create(key=private_key)
jws_msg = jws.JWSMessage.sign(
    payload=payload,
    alg=jwa.RS256,
    key=private_key,
    protected=protected_header,
)

serialized_jws = jws_msg.json_dumps(indent=2).decode('utf-8')
print(f"\nSigned JWS:\n{serialized_jws}")

# 4. Verify the message
# The verifier typically has the public key corresponding to the signer's private key.
parsed_jws = jws.JWSMessage.json_loads(serialized_jws.encode('utf-8'))

try:
    verified_payload = parsed_jws.verify(
        verifier_key=private_key.public_key, # Use the public key for verification
        alg=jwa.RS256
    )
    print(f"\nVerification successful! Payload: {verified_payload.decode('utf-8')}")
    assert verified_payload == payload
except Exception as e:
    print(f"\nVerification failed: {e}")

view raw JSON →