[PYTHON] Verify JWT signature with PyJWT using PKCS # 1 format public key

Learn how to use a public key to validate and decode a JWT signature at PyJWT if the JWT was created with an RS256 format signature. ..

Advance preparation

To support RSA signatures as described in the PyJWT documentation, install the dependent package cryptography along with PyJWT.

$ pip install pyjwt
$ pip install cryptography

To build cryptography, you need to have packages such as libffi-devel and openssl-devel installed in the Linux environment, so if the above $ pip install cryptography fails to install, use these. please confirm. In OS X, it is also necessary to set environment variables, which is rather complicated. See the cryptography installation documentation (https://cryptography.io/en/latest/installation/) for more information.

Public key example

Suppose you have the following public key in pub_key.pem:

pub_key.pem


-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAuDopA35ZLa1sgi2QTFbZjH63BrhXw4evehjDiLHrSc5s+jKMSqfd
6BLoQhN7jcOBnofQB/3rEoy6YXkW58lEtVmekQtYAHh11oB8TBBqzNZP1QxKXWjz
8Jely5bJZHztZEzfddDR7yVZF0VSEa0KjiHbqCdAqXKYuAzUMN4dFyS/q0JXvGAr
Jq/LXyVC3EptcZki02p3Nd6KDZHW7hcj+p0xgYNiGCHO7yLf3uHP+7pak5TW0dWf
MC9fl1/oYFILuasW7OV75+vJGs8d92joEC/Lx3S8+gi3z0CWMnCKrWiTtaAKAq8W
yp4Go8WczOQ1rP+bzDj7b/9M3xrjqY3F0wIDAQAB
-----END RSA PUBLIC KEY-----

By the way, the format instructions "----- BEGIN RSA PUBLIC KEY -----" and "----- END RSA PUBLIC KEY -----" are missing from this key data, which is the cause. I have failed to verify with.

Decode JWT with PyJWT

When not verifying the signature

The code without validation looks like this:

import jwt

encoded_jwt = 'JWT data'
decoded_data = jwt.decode(encoded_jwt, verify=False)

You can omit signature verification by specifying False in the verify argument of the jwt.decode () function in this way. The default value for the verify argument is True, so you must explicitly specify False.

When verifying signature

Next is the code for verifying the signature.

from Crypto.PublicKey import RSA
import jwt

encoded_jwt = 'JWT data'

rsa_public_key_pem = open('path/to/pub_key.pem', 'r').read()
rsa_key = RSA.importKey(rsa_public_key_pem)
key = rsa_key.exportKey()

decoded_data = jwt.decode(encoded_jwt, key=key, verify=True)

Read the above public key and first open the RSA key through the RSA.importKey () method Convert to an object. The key data obtained from the exportKey () method of this RSA key object. Specify in the key argument of the jwt.decode () function. Then specify True for the verify argument to indicate signature verification.

If you specify the RSA public key string as it is in the key argument of the jwt.decode () function without converting the key data by the RSA key object, you will get the error `ValueError: Could not unserialize key data.`. I will.

Recommended Posts

Verify JWT signature with PyJWT using PKCS # 1 format public key
Ssh connection using public key