{"id":5275,"library":"jwskate","title":"JWSkate (JSON Web Crypto for Python)","description":"JWSkate is a Pythonic implementation of the JOSE (JSON Object Signing and Encryption) / JSON Web Crypto related RFCs, including JWS, JWK, JWA, JWT, and JWE. It simplifies cryptographic operations by providing a consistent API built on top of the `cryptography` library. The current version is 0.12.2, with an active release cadence, typically seeing several updates per year.","status":"active","version":"0.12.2","language":"en","source_language":"en","source_url":"https://github.com/guillp/jwskate/","tags":["JOSE","JWS","JWK","JWA","JWT","JWE","cryptography","security","RFC7515","RFC7519"],"install":[{"cmd":"pip install jwskate","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used for all underlying cryptographic operations.","package":"cryptography","optional":false},{"reason":"Used for binary data manipulations.","package":"binapy","optional":false}],"imports":[{"symbol":"Jwk","correct":"from jwskate import Jwk"},{"symbol":"Jwt","correct":"from jwskate import Jwt"},{"symbol":"Jws","correct":"from jwskate import Jws"},{"symbol":"Jwe","correct":"from jwskate import Jwe"},{"symbol":"SymmetricJwk","correct":"from jwskate import SymmetricJwk"},{"symbol":"InvalidSignature","correct":"from jwskate import InvalidSignature"}],"quickstart":{"code":"from jwskate import Jwk, Jwt, InvalidSignature\n\n# 1. Generate a private RSA key for signing\nprivate_jwk = Jwk.generate(alg=\"RS256\", key_size=2048, kid=\"my-rsa-key\")\npublic_jwk = private_jwk.public_jwk()\n\n# 2. Define claims for the JWT\nclaims = {\"sub\": \"user123\", \"name\": \"John Doe\", \"iat\": 1678886400, \"exp\": 1678890000}\n\n# 3. Sign the JWT\ntry:\n    signed_jwt = Jwt.sign(claims, private_jwk)\n    print(f\"Signed JWT: {signed_jwt.compact()}\")\nexcept Exception as e:\n    print(f\"Error signing JWT: {e}\")\n    exit(1)\n\n# 4. Verify the JWT signature (using the public key)\ntry:\n    # The verify_signature method requires the expected algorithm for security\n    if signed_jwt.verify_signature(public_jwk, alg=\"RS256\"):\n        print(\"JWT signature is valid!\")\n        print(f\"Decoded claims: {signed_jwt.claims}\")\n        assert signed_jwt.claims == claims\n    else:\n        print(\"JWT signature verification failed.\")\nexcept InvalidSignature:\n    print(\"Invalid signature detected!\")\nexcept Exception as e:\n    print(f\"Error verifying JWT: {e}\")","lang":"python","description":"This quickstart demonstrates how to generate an RSA key pair, sign a JSON Web Token (JWT) with the private key, and then verify its signature using the corresponding public key. It highlights the importance of specifying the expected algorithm during verification."},"warnings":[{"fix":"Update method calls to use the new parameter names (e.g., `key` instead of `jwk`).","message":"In v0.11.0, several method parameters accepting a Jwk instance (e.g., `jwk`, `sig_jwk`, `enc_jwk`) were renamed to `key`, `sig_key`, or `enc_key`. They now also accept a `dict` or a `cryptography` key directly.","severity":"breaking","affected_versions":">=0.11.0"},{"fix":"Use `SymmetricJwk` for symmetric key operations, explicitly call `decrypt_with_password()` when applicable, and pass encryption algorithms via the `enc` parameter.","message":"In v0.12.2, `decrypt_with_password()` was separated from `decrypt()`, which no longer accepts a password. Encryption/decryption methods were moved to `SymmetricJwk`, and the `enc` parameter is now preferred over `alg` for encryption algorithms.","severity":"breaking","affected_versions":">=0.12.2"},{"fix":"Always pass the expected algorithm (e.g., `alg=\"RS256\"` or `algs=[\"ES256\", \"ES384\"]`) to `verify_signature` and similar methods.","message":"For all signature verification methods, you **must** explicitly provide the expected signature algorithm(s) (via `alg` or `algs` parameters). This prevents critical security vulnerabilities like 'none' algorithm attacks, where an attacker could bypass signature checks by setting `alg` to 'none' in the token header. JWSkate will ignore the `alg` header in the token for security reasons if not explicitly provided or inherited from the key.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use the `.to_json()` method (e.g., `jwk.to_json()`) or convert to a standard dictionary (`dict(jwk)`) before serializing with `json.dumps()`.","message":"Jwk, Jwt, Jws, and Jwe objects are subclasses of `collections.UserDict` (or `dict` in older versions), making them behave like dictionaries. However, they are not natively JSON serializable using Python's default `json.dumps()`. Attempting to do so will result in a `TypeError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware of the behavior of `Jwk.kid` vs. `jwk['kid']` when interacting with key identifiers.","message":"The `Jwk.kid` property returns the key's thumbprint (RFC7638) if a `kid` attribute is not explicitly present in the JWK. If you need the literal `kid` value as stored in the JWK, access it directly as `jwk['kid']`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}