Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python JWT library PyJWT trouble signing with HS256 - HMAC using SHA-256 hash algorithm

Tags:

python

jwt

pyjwt

Trying to generate a JWT token using the PyJWT library.

When I use the below program to generate the JWT token - the token does not work.

However when I use the website https://jwt.io/ with the same details - the token works. Is there something that I'm missing.

I need python generate the token properly so I can automate some API's that need this token.

Python program:

import jwt
import base64

code = jwt.encode({'sub':'String','nbf':'1501594247',
                   'exp':'1501767047', 'iss': 'string', 'aud': 'String'},
       base64.b64encode('secret'), algorithm='HS256')
print code

Example:

code = jwt.encode({'sub':'AccountNUmber.QTVR','nbf':'1501594247','exp':'1501860089', 'iss': 'client_id', 'aud': 'https://login.google.com/oauth'},
                  base64.b64encode('secret'), algorithm='HS256')

Result:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnRfaWQiLCJhdWQiOiJodHRwczovL2xvZ2luLmdvb2dsZS5jb20vb2F1dGgiLCJzdWIiOiJBY2NvdW50TlVtYmVyLlFUVlIiLCJleHAiOiIxNTAxODYwMDg5IiwibmJmIjoiMTUwMTU5NDI0NyJ9.dRUUQYJ-RmxgoExwPyrvHPzX9SsxcpX1rOWlhisxNsg

Token generated by https://jwt.io/ :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnRfaWQiLCJhdWQiOiJodHRwczovL2xvZ2luLmdvb2dsZS5jb20vb2F1dGgiLCJzdWIiOiJBY2NvdW50TlVtYmVyLlFUVlIiLCJleHAiOiIxNTAxODYwMDg5IiwibmJmIjoiMTUwMTU5NDI0NyJ9.INp-ZnnL8Uj7MIwLYmpZtGyTyZG-oqZRNW8iZ145jVs

The token generated by https://jwt.io/ works when I call the endpoint. And I get a status code 200 (Success).

However when I use the token generated from my program it gives 'Invalid Token' - 400 (Bad Request).

like image 509
Michael Eltham Avatar asked Aug 02 '17 20:08

Michael Eltham


1 Answers

The error here is the base64.b64encodein your python statement. You are not supposed to encode the secret before you pass it to jwt.encode. I think the jwt.io debugger is a bit misleading in this regard:

enter image description here

The idea here is, that you have a secret that is stored in base64 encoded format somewhere and the jwt.io debugger will decode your secret when you tell him that it is encoded.

As you can check easily in idle:

>>> base64.b64encode('secret')
'c2VjcmV0'

And if you paste the encoded secret to the secret field on jwt.io and check the checkbox as shown in the picture above, you'll get the following token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnRfaWQiLCJhdWQiOiJodHRwczovL2xvZ2luLmdvb2dsZS5jb20vb2F1dGgiLCJzdWIiOiJBY2NvdW50TlVtYmVyLlFUVlIiLCJleHAiOiIxNTAxODYwMDg5IiwibmJmIjoiMTUwMTU5NDI0NyJ9.Nk6oCKBlT9lh4rtJZzF8JuyEsiH_HBaa3UhUx3DbWeI

which is identical to the output of the follwing python programs:

a) when you provide a secret directly, not encoded:

code = jwt.encode({'sub':'AccountNUmber.QTVR','nbf':'1501594247','exp':'1501860089', 'iss': 'client_id', 'aud': 'https://login.google.com/oauth'}, 
                  'secret', algorithm='HS256')

b) when you provide an encoded secret:

code = jwt.encode({'sub':'AccountNUmber.QTVR','nbf':'1501594247','exp':'1501860089', 'iss': 'client_id', 'aud': 'https://login.google.com/oauth'},
                  base64.b64decode('c2VjcmV0'), algorithm='HS256')

This should work.

like image 170
jps Avatar answered Oct 26 '22 04:10

jps