Validate JWT Token


https://auth0.com/docs/secure/tokens/json-web-tokens/locate-json-web-key-sets 

To convert a JWKS (JSON Web Key Set) `x5c` (X.509 certificate chain) to PEM format in Python, you can use libraries like `cryptography` and `base64`. The `x5c` parameter contains the certificate chain in base64-encoded DER format, and you need to decode it to convert it into PEM format.

Here's a step-by-step guide and the corresponding Python code:

### Step-by-Step Process

1. **Install Necessary Libraries**: You need the `cryptography` library to handle the certificate conversion. If it's not installed, you can install it using pip:

```bash
pip install cryptography
```

2. **Import Libraries**: Import the necessary libraries for handling base64 and cryptography functions.

3. **Extract the x5c Certificate**: Extract the first certificate from the `x5c` array. This is typically the leaf certificate that you want to convert.

4. **Decode the Base64 Certificate**: Decode the base64-encoded certificate from the `x5c` array.

5. **Convert to PEM Format**: Use the `cryptography` library to convert the decoded certificate to PEM format.

6. **Print or Save the PEM**: Print or save the PEM format certificate as needed.

### Example Code

Here is the complete Python code to perform the conversion:

import base64
from cryptography import x509
from cryptography.hazmat.primitives import serialization

# Sample JWKS x5c entry
jwks = {
    "keys": [
        {
            "kty": "RSA",
            "use": "sig",
            "kid": "1b94c",
            "x5t": "1b94c",
            "x5c": [
                "MIIDQzCCAqygAwIBAgIGANiDqDRzMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMRYwFAYD
                 VQQKEw1FeGFtcGxlIEluYy4xEDAOBgNVBAsTB0V4YW1wbGUxEDAOBgNVBAMTB0V4YW1wbGUxHTAb
                 BgkqhkiG9w0BCQEWDmV4YW1wbGUuY29tMB4XDTExMDEwMTAwMDAwMFoXDTIxMDEwMTAwMDAwMFow
                 YjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUV4YW1wbGUgSW5jLjEQMA4GA1UECxMHRXhhbXBsZTEQ
                 MA4GA1UEAxMHZXhhbXBsZTEdMBsGCSqGSIb3DQEJARYOZXhhbXBsZUBleGFtcGxlLmNvbTCCASIw
                 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8AP6o6LzW68FZXF4c3gU1q4szU2NyZf2fsBF2x
                 7L8Hi7vh5PS3LVC1b9nkg4QQoVROv4iHCJPC6vQL1Pjk7Xb48tcdiR8H5E0pHpZZy7yRQU5R4ZSy
                 hmXP8KszV39um7ROnPEA0iE7okFOqhFKaBFPQ8x4+8bRbLNRvT+Ajc8Vq0XZJHJs4H0kCkgvB3T1
                 VLk0t3ZXMyZ7RHZ8o5JZmjdsKEzxv5kjFWzQXoX66Kq3KUD44C5tNqIl4HN6mygrm0P2HFz3txa6
                 Oq65LqJYVJ+Gdi5q9NVJggJlD2lD7q3BGN45SGH56uB7g6t5sUdL0z4MeTmOhJX7PqBaTyPYMCOU
                 RIECAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQIwDQYJKoZIhvcN
                 AQEFBQADggEBABRmaQoea2f32wGxdm/S4JN7r2nV0Dk54RCeyyptc6FZp4U9gKm3aIDR4/XHWH/k
                 +X9G4BgqOqaDOP1g6Txz+1WlKHeaN1x6fUpxvtwutVJW0GgM4K6g/7p9cq7YFDmaXlDXD5w1Un5x
                 k1lw20h3f2RVOJ9vDafhe2l7r4+a1Q+YYPOFhA2N0L5nBWVndppkOnUKu+EXr3nJpxzTNWs3mB4c
                 ES7Cke+IOJJ8/x4hy9RRMZf7zBB9F3vWeKBlQpAapStn6w3xqPi3PjFq5uJ3/p0YEekEVC6E3l5z
                 +f9AubS1Zz7TzL2P+8KFPwxg2SvF0V9hHD+XllXU5P8Cd6ShnwqKpjQ=",
                # Add additional certificates if needed
            ]
        }
    ]
}

def convert_x5c_to_pem(jwks):
    # Get the first x5c entry
    x5c_base64 = jwks["keys"][0]["x5c"][0]

    # Decode the base64-encoded certificate
    x5c_der = base64.b64decode(x5c_base64)

    # Load the certificate using cryptography
    certificate = x509.load_der_x509_certificate(x5c_der)

    # Convert the certificate to PEM format
    pem_certificate = certificate.public_bytes(serialization.Encoding.PEM)

    return pem_certificate.decode("utf-8")

# Convert and print the PEM format certificate
pem_certificate = convert_x5c_to_pem(jwks)
print(pem_certificate)

Note:



### Explanation

1. **Import Libraries**: The code uses `base64` for decoding and `cryptography` for handling certificate conversions.

2. **Extract the x5c Certificate**: The first certificate in the `x5c` array is extracted. It's common to convert only the leaf certificate, but you can handle the entire chain if needed.

3. **Decode the Certificate**: The `base64.b64decode()` function decodes the base64-encoded string into DER format, which is the binary format for X.509 certificates.

4. **Load and Convert the Certificate**: The `cryptography.x509.load_der_x509_certificate()` function loads the DER-encoded certificate, and then it's converted to PEM format using the `public_bytes()` method with `serialization.Encoding.PEM`.

5. **Output**: The PEM format certificate is returned as a UTF-8 string and printed.

### Output

The output will be a PEM-formatted certificate like this:

```plaintext
-----BEGIN CERTIFICATE-----
MIIDQzCCAqygAwIBAgIGANiDqDRzMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYT
AlVTMRYwFAYDVQQKEw1FeGFtcGxlIEluYy4xEDAOBgNVBAsTB0V4YW1wbGUxEDAO
...
k1lw20h3f2RVOJ9vDafhe2l7r4+a1Q+YYPOFhA2N0L5nBWVndppkOnUKu+EXr3nJ
pxzTNWs3mB4cES7Cke+IOJJ8/x4hy9RRMZf7zBB9F3vWeKBlQpAapStn6w3xqPi3
PjFq5uJ3/p0YEekEVC6E3l5z+f9AubS1Zz7TzL2P+8KFPwxg2SvF0V9hHD+XllXU
5P8Cd6ShnwqKpjQ=
-----END CERTIFICATE-----
```

### Handling Certificate Chain

If you need to convert the entire certificate chain, you can iterate over all entries in the `x5c` array:

def convert_x5c_chain_to_pem(jwks):
    pem_chain = []
    for cert_base64 in jwks["keys"][0]["x5c"]:
        # Decode the base64-encoded certificate
        cert_der = base64.b64decode(cert_base64)

        # Load the certificate
        certificate = x509.load_der_x509_certificate(cert_der)

        # Convert to PEM
        pem_certificate = certificate.public_bytes(serialization.Encoding.PEM)

        pem_chain.append(pem_certificate.decode("utf
import jwt
from jwt import PyJWTError, InvalidTokenError, ExpiredSignatureError, InvalidSignatureError, InvalidAudienceError
from cryptography.hazmat.primitives import serialization

# Sample token and public key
token = "your.jwt.token.here"
public_key = """
-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_HERE
-----END PUBLIC KEY-----
"""

def validate_jwt_rs256(token, public_key):
    try:
        # Decode the token
#If the aud claim on the token is set (on yours it is set to 'some-aud') then decoding MUST specify an expected aud value using the audience argument for #decode() otherwise decoding will fail with an InvalidAudienceError.

#Please see: https://github.com/jpadilla/pyjwt#audience-claim

        payload = jwt.decode(
            token,
            public_key,
            algorithms=["RS256"],  # Use the correct algorithm
            options={"verify_exp": True}  # Verify expiration
        )
        
        # Successfully decoded token
        print("Token is valid.")
        print("Payload:", payload)
        return payload

    except ExpiredSignatureError:
        print("Token has expired.")
    except InvalidSignatureError:
        print("Signature verification failed.")
    except InvalidAudienceError:
        print("Invalid audience.")
    except InvalidTokenError:
        print("Invalid token.")
    except PyJWTError as e:
        print("Token validation failed:", str(e))
        
    return None

# Validate the JWT with RS256
payload = validate_jwt_rs256(token, public_key)



  


Comments:

Write a comment
Anonymous

Captcha image

Reload

Type the number you see in the image above: