pyjwt: RSA256 not supported despite having cryptography (was: pycrypto) installed

Python 3.2.3 on a RPi (Linux raspberrypi 3.18.11+ #781 PREEMPT Tue Apr 21 18:02:18 BST 2015 armv6l GNU/Linux).

PyCrypto is installed:

pycrypto                  - Cryptographic modules for Python.
  INSTALLED: 2.6.1 (latest)

python3-dev and python3-crypto are installed as well. Note: the same issue is present whether either of pycrypto or python3-crypto are installed, or both, or neither.

The following call crashes with an unsupported algorithm:

myjwt = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}).decode('utf-8')

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python3.2/dist-packages/jwt/api_jws.py", line 96, in encode
    alg_obj = self._algorithms[algorithm]
KeyError: 'RS256'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.2/threading.py", line 740, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.2/threading.py", line 693, in run
    self._target(*self._args, **self._kwargs)
  File "galarmclock.py", line 241, in getcalendar
    gauth.gettoken()
  File "/root/galarmclock/googleauth.py", line 32, in gettoken
    myjwt = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}).decode('utf-8')
  File "/usr/local/lib/python3.2/dist-packages/jwt/api_jwt.py", line 56, in encode
    json_payload, key, algorithm, headers, json_encoder
  File "/usr/local/lib/python3.2/dist-packages/jwt/api_jws.py", line 101, in encode
    raise NotImplementedError('Algorithm not supported')
NotImplementedError: Algorithm not supported

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 6
  • Comments: 25 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for reporting @wsw70.

One small thing first. You don’t need to include the headers value in your call. Those headers will be automatically populated by PyJWT when it is creating the token. The headers parameter is for adding additional header parameters besides just those required by the spec.

Regarding your actual issue… some time ago we switched to using cryptography as the preferred cryptographic library for PyJWT. We switched for a number of reasons (most notably: the fact that cryptography is a much better implementation and is faster than PyCrypto). I strongly recommend that, if possible, you run pip install cryptography and install the cryptography package. That will resolve the issue.

If you are unable to install cryptography we do have legacy support for PyCrypto but this is not recommended unless you are on a platform (like Google App Engine) that doesn’t allow you to use cryptography.

You can setup the legacy support for algorithms by doing the following:

>>> import jwt
>>> from jwt.contrib.algorithms.pycrypto import RSAAlgorithm
>>> jwt.register_algorithm('RS256', RSAAlgorithm(RSAAlgorithm.SHA256))
>>> jwt.encode(claim, private_key, algorithm='RS256')

@mark-adams I use like this, but I catch the following error.

import jwt
from jwt.contrib.algorithms.pycrypto import RSAAlgorithm
jwt.register_algorithm('RS256', RSAAlgorithm(RSAAlgorithm.SHA256))
jwt.encode(claim, private_key, algorithm='RS256')

raise ValueError(‘Algorithm already has a handler.’) ValueError: Algorithm already has a handler.

I have the same problem like a @pcwang0205 . @pcwang0205 , Did you solve your problem?

@goginenir6 you can use like this: pip install pyjwt

import jwt
token = jwt.encode(payload, constants.PRIVATE_RSA_KEY, algorithm='RS256')

@mark-adams I moved the development of my soft to docker and ran into the same problem (I am a bit desperate but at least googling the issue brings be back here 😃)

The Dockerfile (which builds the docker container) calls

apt install python3-cryptography python3-jwt

This is on an Ubuntu 16.10 (yakkety)

When starting my program I run into

xception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/jwt/__init__.py", line 179, in encode
    key = prepare_key_methods[algorithm](key)
KeyError: 'RS256'
 
During handling of the above exception, another exception occurred:
 
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.4/threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
  File "webserver.py", line 219, in calendar
    allevents = gcal.getevents(calendars, days_back=1, days_ahead=7)
  File "/opt/googlecalendar.py", line 58, in getevents
    self.gettoken()
  File "/opt/googlecalendar.py", line 38, in gettoken
    gjwt = jwt.encode(payload, bytes(json_data['private_key'], 'UTF-8').decode('utf-8'), algorithm='RS256')
  File "/usr/lib/python3/dist-packages/jwt/__init__.py", line 182, in encode
    raise NotImplementedError("Algorithm not supported")
NotImplementedError: Algorithm not supported

TL;DR: do not make my mistake, do not install PyJWT via the OS package manager. In other words RTFM which tells to install vi apip 😃

I still kept below the story of my bumpy journey, just in case I am back here again


I needed to install my script on another machine (the current one was working fine, honestly I do not remember how I managed to make it swallow the RS256 algorithm but it works untouched for 9 months) and I bumped against the same issue. Installing cryptography did not help (Python 3). A google search brought me here back 😃

The solution I used was not to switch to the legacy behaviour @mark-adams suggested (otherwise it would have worked on the new install) .

For the sake of our civilization (and in case I am back here again) - the whole story on what to install and what not (on a RP with raspbiani, so a debian derivative but it may be the same on other distros).

I installed cryptography via the package manager. I realized after some time that the antique version 0.6 was installed. Uninstalled it via apt purge python3-cryptography

Tried a pip3 install cryptography --upgrade.

ffi.hwas missing, installed with libffi-dev

cffi.setuptools_ext was missing, installed pip3 install cffi --upgrade

opensslv.h, fixed by apt install libssl-dev

After that pip3 install cryptography --upgrade worked but the algorithm was still unknown.

I removed the package and installed PyJWTvia pip3. It finally worked and I ws able to get a JWT for Google.