Signing JWT Token With JWK Private Key Using PyJWT

JWK is a JSON that represents a cryptographic key. PyJWT is a pretty popular Python library to generate, verify JWT token. But one drawback is that it doesn’t support JWK format, at least it is not properly documented.

Suppose we have an RSA private key, but it is given in JWK format. Our objective is to create & sign a JWT token with this JWK key using PyJWT.

The main thing we need to do is to extract the private key from JWK format so that PyJWT sign method jwt.encode() can use it.
This line will do that for you.

private_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk))

Let’s take a look at the complete example.
Private key in JWK format:

        {
            "p": "1uitddxhPb5jydbh9cTm_3uIkqAazNI3yDSonnLtGMM",
            "kty": "RSA",
            "q": "tteZx40Cl1Sbb_1aSTOl5cr-JEVF2N46_5RAEO_rde0",
            "d": "TYCR6PtuD7qdwX9wWB3mMCiAs0t18CAO3NwSZ3Vw-WkrOxAoXMvp6hcUKlwB47VactN1-tIdqO1Li44zZquEiQ",
            "e": "AQAB",
            "use": "sig",
            "qi": "Wi4KwJfXLa5ktChVpm4Aed4hZs94ifdQLuGeNjaHPqo",
            "dp": "5S07zXQ2PqHJyHRegrh3nfseqT4TVljXI6kEJ_Rm4w",
            "alg": "RS256",
            "dq": "bYBHn6PKhnjsMjCn7qkY1LsyYuR9xTiqWsAdckdNW60",
            "n": "mX5p1A2T00otyLHypNCWQPV2TwzYDfi8TqdkIGXvowCHnjf2z3TTnLG93ewlmAT4lieYiI8Ph3QjTasqidILhw"
        }

Fully working Python code to generate JWT token & sign it using the above JWK:

import time
import json
import jwt

def generate_jwt():
    current_time_in_seconds = round(time.time())
    expiry_time_in_seconds = current_time_in_seconds + 600
    claims={"exp": expiry_time_in_seconds, "iat":current_time_in_seconds}
    jwk={"p": "1uitddxhPb5jydbh9cTm_3uIkqAazNI3yDSonnLtGMM", "kty": "RSA", "q": "tteZx40Cl1Sbb_1aSTOl5cr-JEVF2N46_5RAEO_rde0", "d": "TYCR6PtuD7qdwX9wWB3mMCiAs0t18CAO3NwSZ3Vw-WkrOxAoXMvp6hcUKlwB47VactN1-tIdqO1Li44zZquEiQ", "e": "AQAB", "use": "sig", "qi": "Wi4KwJfXLa5ktChVpm4Aed4hZs94ifdQLuGeNjaHPqo", "dp": "5S07zXQ2PqHJyHRegrh3nfseqT4TVljXI6kEJ_Rm4w", "alg": "RS256", "dq": "bYBHn6PKhnjsMjCn7qkY1LsyYuR9xTiqWsAdckdNW60", "n": "mX5p1A2T00otyLHypNCWQPV2TwzYDfi8TqdkIGXvowCHnjf2z3TTnLG93ewlmAT4lieYiI8Ph3QjTasqidILhw"}
    private_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk))
    signed_jwt = jwt.encode(claims, private_key, algorithm="RS256")
    print(signed_jwt)


generate_jwt();

By the way, this is just an example & I am using a random private key for testing. Do not expose your private key outside ever.

Leave a Comment