Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wsw70 opened this issue Oct 9, 2015 · 25 comments
Closed
Labels

Comments

@wsw70
Copy link

wsw70 commented Oct 9, 2015

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
@mark-adams
Copy link
Contributor

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')

@wsw70
Copy link
Author

wsw70 commented Oct 9, 2015

Thank you for the clear answer, I will go for cryptography and fallback to the legacy support if there are problems.

@wsw70 wsw70 closed this as completed Oct 9, 2015
@cblair
Copy link

cblair commented Feb 26, 2016

Legacy fix fixed for me as well.

@muhammad-meraj
Copy link

@mark-adams , Thanks, your answer fix my problem as well.

@wsw70
Copy link
Author

wsw70 commented Jul 31, 2016

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.

@wsw70
Copy link
Author

wsw70 commented Aug 27, 2016

@mark-adams

I strongly recommend that, if possible, you run pip install cryptography and install the cryptography package. That will resolve the issue.

I started from a fresh install of Windows (python 3.5), installed cryptography as you suggested (it is now statically linked so the install is a breeze on Windows, no need for a compiler anymore) but the issue stayed (I installed pyJWT via pip earlier).

Is there anything special I need to do in order to decal re this algorithm to pyJWT?

@wsw70 wsw70 reopened this Aug 27, 2016
@wsw70 wsw70 changed the title RSA256 not supported despite having PyCrypto installed RSA256 not supported despite having cryptography installed Aug 27, 2016
@wsw70 wsw70 changed the title RSA256 not supported despite having cryptography installed RSA256 not supported despite having cryptography (was: pycrypto) installed Aug 27, 2016
@mark-adams
Copy link
Contributor

@wsw70 No, that should work. Are you sure that both cryptography and pyjwt are both being installed in the same environment / virtualenv? Also, can you confirm both are importable from a Python shell?

@wsw70
Copy link
Author

wsw70 commented Dec 21, 2016

@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

@wsw70
Copy link
Author

wsw70 commented Dec 21, 2016

@mark-adams I started once again (on a clean distribution), this time not installing python3-jwt but going for pip3 install PyJWT (having installed python3-cryptography before). Everything works fine.

There must be something wrong with the version in the distribution.

@mark-adams
Copy link
Contributor

mark-adams commented Aug 25, 2017

That makes sense. Probably should file a bug with the upstream distro. Thanks for looking into it.

@finnome
Copy link

finnome commented Nov 21, 2017

@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.

@charlesardsilva
Copy link

charlesardsilva commented Feb 8, 2018

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

@goginenir6
Copy link

goginenir6 commented Feb 12, 2018

I have also got same problem @pcwang0205 and @charlesasilva61 . Is this problem solved?
@mark-adams or anyone
Could you please take a look at once. I am using "google app engine."

@finnome
Copy link

finnome commented Feb 25, 2018

@goginenir6
you can use like this:
pip install pyjwt

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

@apple-blossom
Copy link

Had the same problem, the solution was just to delete line with jwt.register_algorithm()
so:
import jwt ... payload = {...} key = self.copy_file_text('some-key.txt') result = jwt.encode(payload, key, algorithm='RS512')
By the way, Pycrypto is deprecated, used Pycryptodome instead (python v3.6)

@marcboissonneaultjda
Copy link

@apple-blossom:
pycryptodome is not part of the "built-in Third party libraries" in app engine. And even once installed through the vendor process, it seems to use some C libraries.

File "/base/data/home/apps/projectX/lib/Crypto/Hash/SHA256.py", line 23, in <module> from Crypto.Util._raw_api import (load_pycryptodome_raw_lib, File "/base/data/home/apps/projectX/lib/Crypto/Util/_raw_api.py", line 111, in <module> from ctypes import (CDLL, c_void_p, byref, c_ulong, c_ulonglong, c_size_t, File "/base/alloc/tmpfs/dynamic_runtimes/python27/a7637d5531ec9deb_unzipped/python27_dist/lib/python2.7/ctypes/__init__.py", line 7, in <module> from _ctypes import Union, Structure, Array ImportError: No module named _ctypes

I'm guessing the right suggestion is to use cryptography like mentioned above....

@caseyduquettesc
Copy link
Contributor

If anyone is getting the "Algorithm already has a handler" problem, there's a simple fix. Unregister the original handler first.

import jwt

# Tell pyjwt to use pycrypto instead of cryptography, which isn't available on GAE
# https://github.com/jpadilla/pyjwt/blob/master/docs/installation.rst#legacy-dependencies
from jwt.contrib.algorithms.py_ecdsa import ECAlgorithm

jwt.unregister_algorithm('ES256')
jwt.register_algorithm('ES256', ECAlgorithm(ECAlgorithm.SHA256))

jpadilla pushed a commit that referenced this issue Mar 23, 2018
Related to #181 where users see `ValueError: Algorithm already has a handler.` after trying to register pycrypto algorithms.
@FelikZ
Copy link

FelikZ commented May 31, 2018

I think it worth to mention cryptography requirement in README.md , otherwise people will end-up here trying to figure out why it does not work :)

@srikanthjeeva
Copy link

Adding cryptography to my requirements.txt solved the issue :) Thanks!

@chadjaros
Copy link

chadjaros commented Jul 23, 2018

👍 add to readme please. Or better yet, add to install_requires in setup.py

@jpadilla
Copy link
Owner

We need to update docs, but pip install pyjwt[crypto] should work.

@Deepakthakur53
Copy link

I am trying to use , PS256 and getting below error, if I change algorithm for HS256 code is working well and good.

below is the error I am getting.

NotImplementedError: Algorithm 'PS256' could not be found. Do you have cryptogra
phy installed?

@wsw70
Copy link
Author

wsw70 commented Jun 5, 2019

@Deepakthakur53 : so you have cryptography installed?

Also please look at my TL;DR comment (#181 (comment)) where I found out that all this needs to be installed via pip and not apt, yum or other system packager.

I use pyjwt in a docker container and the installation is painless now (again, when using pip)

@stathismor
Copy link

stathismor commented Jul 28, 2020

Any idea/workaround for someone like me who wants to use from_jwk that is not implemented in the legacy class? @mark-adams your workaround (from 5 years ago 😄 ) works, but not for this function.

@TaxableApples
Copy link

I don't normally add to things like this, but I spent two days trying to resolve this exact error in an AWS Lambda. Using the correct python / pip version to match my environment, and installing cryptography and then pyjwt was key, however I would have solved it a lot sooner if I had realized that in AWS Lambda, the layer version attached to your Lambda Function does not always automatically update when you create a new layer version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests