在python中使用PyJWT解码jwt令牌,给出错误算法不受支持



我正在使用PyJWT来解码来自keycloft的JWT令牌。

eyJhbGciOiJSUzi1NiIsInR5cIgOiAiSldUIiwia2lkIiA6ICJ6MWpiUExrndMVTBkTHk3a0NIT1pyS2FJd3FPMXFrbThDeGtvVHg2QzFBIn0.eyJleHAiOjE2MjE0MjQwMjEsImlhdCI6MTYyMTQyMzk2MSSwiYXV0aF90aW1lIjoxNjIxNDIxNzc0LCJqdGkiOiIwYzY2Y2I0My1lMGY1LTQzNjItc2MS1lN2OW VhNDM5MjUILJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIwiYXVkIjpbIM1Hc1yzWFsbSIsImFjY291bnQiXSwic3ViIjoiN2Y2ODBlN2MtZGM4Yy00ZGJiLWJiZDEtMTE0ZGJhYjA2Zjc1IidHlwIjoiQmVhcmVyIiwiYXPwIjoiYW11bmRzW4tZnJvbnRlbmQiLCJzZXNzaW9uX3N0YXRlIjoiYTM5YzJlNmUtZGNjMS00OTM5LTg0ODITYzk2NGE5ODMxNmYyIiwiNyYWIjoiMSIsImFsbG93ZWQtb3JpZ2lucy6WyJodHRwOi8vbG9jYWb3N0OjUwMDAi LCJsb2NhbGhvc3Q6NTAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9ZXMiOlsiY3JlYXRlLXJlYWxtIiwb2ZmbGluZV9hy2Nlc3MiLCJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXjZV9h Y2Nlc3miOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbInZpZXctcmVhbG0iLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYxRlLWNsaWVudCIsIm1hbmFnZS11c2VycyISIn1ZXJ5LXJlyWxtyIsInzpZXctYXV0aG9XpyahdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycysIm1hbmFnZS1ldmVudHMi LCJtYW5hZ2UtcmVhbG0i LCJ2aWV3LWV2ZW50cysInZpZXctdXNlcnMi LCJ2a WV3LWNsaWVud HMi LCjtYW5HZ2UtYXv0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIwicXVlcnktZ3JvdXBzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIM1hbmFnZS1hY2Nvdw50IwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYwlsIwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiYwrt aW5maXzdCBhZG1bmxhc3QiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiImdpdmVuX25hbWUioiJhZF1bmZpcn0IiwiZmFtaWx5X25hbWuiOiJwZG1bmyxc3QiLCjlbWFpbCI6ImFkbWludGVzdEBnbWFpbC5jb20ifQ.aksSjBU5hJ1rtn43NtbMt8E6gaGmJXDrtGDI7j0T7eo6AcnUxG4spYNNhyksXVr3ZFvua2WyTKnZirqaJUI3zzdLj-XkE7zYCYwoJpjXITmmlj5oszD3pcRdGeyUVyQV49tiUfUFi1KoIt9K016mH2s_beFrN3TYSjuLh5Epdk_dpNBh9YE_1f3pwsEbN2Jgz_j-VB6cQHq17RzWQIVSd6ZvftAWDWdc 6nobOvTy1mZAA_DgsXwdjuNc8Qv36ztuDzkT-raCnuLH479ciBOFQZ0946obIE4ddJKpr7lnVupcbQZ6lDM_QZHz1hwkYqgSU-Ui8NHaWlqt4HJ5-9A

我的代码

import jwt
import traceback

try:
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhlOIQLHXwZoS3w9SBtvZ1ea4ftWmWnP+HCwlvs7XoJ9EhS+ZQEP7Z25tjW3I8mjUVL0XETrOOjQsD8O2nRBqizJsRaB8L9xsXdJmPHVTx7nphaBPtY5YHxxYqpwEC5rAKtx54YJxw6Ggeicmv+xXtaaDf/VALh5xxpa1U6yP5oqk3yV27yA0beQFVsdugkcfYN0C2FldaUcF9yTUf/KNHTYSu3Ar7iN9U+qEHwaznrLShwh7iknldTKTgEw3liHL8K/5ZlqxHPsL02InwZMaIRic3zNIgVvwedroM6nqZBB4mi1+T0dZn4qsNkG4D0w7IE7MTRgyyYARqrGEq5yOFwIDAQAB
-----END PUBLIC KEY-----"""
secret_key = "base-flask-oidc-secret-key"
token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ6MWpiUExrTndMVTBkTHk3a0NIT1pyS2FJd3FPMXFrbThDeGtvVHg2QzFBIn0.eyJleHAiOjE2MjE0MjQwMjEsImlhdCI6MTYyMTQyMzk2MSwiYXV0aF90aW1lIjoxNjIxNDIxNzc0LCJqdGkiOiIwYzY2Y2I0My1lMGY1LTQzNjItYTc2MS1lN2M2OWVhNDM5MjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjpbIm1hc3Rlci1yZWFsbSIsImFjY291bnQiXSwic3ViIjoiN2Y2ODBlN2MtZGM4Yy00ZGJiLWJiZDEtMTE0ZGJhYjA2Zjc1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYW11bmRzZW4tZnJvbnRlbmQiLCJzZXNzaW9uX3N0YXRlIjoiYTM5YzJlNmUtZGNjMS00OTM5LTg0ODItYzk2NGE5ODMxNmYyIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJsb2NhbGhvc3Q6NTAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwib2ZmbGluZV9hY2Nlc3MiLCJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbInZpZXctcmVhbG0iLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsIm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInF1ZXJ5LXJlYWxtcyIsInZpZXctYXV0aG9yaXphdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycyIsIm1hbmFnZS1ldmVudHMiLCJtYW5hZ2UtcmVhbG0iLCJ2aWV3LWV2ZW50cyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtYXV0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiYWRtaW5maXJzdCBhZG1pbmxhc3QiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImdpdmVuX25hbWUiOiJhZG1pbmZpcnN0IiwiZmFtaWx5X25hbWUiOiJhZG1pbmxhc3QiLCJlbWFpbCI6ImFkbWludGVzdEBnbWFpbC5jb20ifQ.aksSjBU5hJ1rtn43NtbMt8E6gaGmJXDrtGDI7j0T7eo6PAcnUxG4spYNNhyksXVr3ZFvua2WyTKnZirqaJUI3zzdLj-XkE7zYCYWoJpjXITmmlj5oszD3pcRdGeyUVyQV49tIiUfUFi1KoIt9K016mH2s_beFrN3TYSjuLh5Epdk_dpNBh9YE_1f3opwsEbN2Jgz_j-VB6cQHq17RzWQIVSd6ZvftAWDWdc6nobOvTy1mZAA_DgsXwdjuNc8Qv36ztuDzkT-raCnuLH479ciBOFQZ0946obIE4ddJKpr7lnVupcbQZ6lDM_QZHz1hwkYqgSU-Ui8NHaWlqt4HJ5-9A"
# token_json = jwt.decode(token, secret_key, algorithms=['HS256', 'RS256'], audience='account')
token_json = jwt.decode(token, public_key, algorithms=['HS256', 'RS256'], audience='account')
print(access_token_json)

except Exception:
print(traceback.print_exc())

据jwt.io报道,它显示的是头标

{
"alg": "RS256",
"typ": "JWT",
"kid": "z1jbPLkNwLU0dLy7kCHOZrKaIwqO1qkm8CxkoTx6C1A"
}

我试过使用公钥和私钥,两者都给了我错误

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 232, in _verify_signature
alg_obj = self._algorithms[alg]
KeyError: 'RS256'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "jwt_test.py", line 16, in <module>
access_token_json = jwt.decode(access_token, public_key, algorithms=['HS256', 'RS256'], audience='account')
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
**kwargs,
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 149, in decode_complete
self._verify_signature(signing_input, header, signature, key, algorithms)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 239, in _verify_signature
raise InvalidAlgorithmError("Algorithm not supported")
jwt.exceptions.InvalidAlgorithmError: Algorithm not supported

如果我正在从算法列表中删除"RS256"。

token_json = jwt.decode(token, public_key, algorithms=['HS256'], audience='account')

那我就错了。

Traceback (most recent call last):
File "jwt_test.py", line 18, in <module>
token_json = jwt.decode(token, public_key, algorithms=['HS256'], audience='account')
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
**kwargs,
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 149, in decode_complete
self._verify_signature(signing_input, header, signature, key, algorithms)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 229, in _verify_signature
raise InvalidAlgorithmError("The specified alg value is not allowed")

我该如何解决这个问题。

提前感谢!

###################回答####################

我能够通过解决它

按照@KlausD在评论中的建议安装加密

pip install cryptography

还将公钥更改为

public_key = """-----BEGIN PUBLIC KEY-----nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhlOIQLHXwZoS3w9SBtvZ1ea4ftWmWnP+HCwlvs7XoJ9EhS+ZQEP7Z25tjW3I8mjUVL0XETrOOjQsD8O2nRBqizJsRaB8L9xsXdJmPHVTx7nphaBPtY5YHxxYqpwEC5rAKtx54YJxw6Ggeicmv+xXtaaDf/VALh5xxpa1U6yP5oqk3yV27yA0beQFVsdugkcfYN0C2FldaUcF9yTUf/KNHTYSu3Ar7iN9U+qEHwaznrLShwh7iknldTKTgEw3liHL8K/5ZlqxHPsL02InwZMaIRic3zNIgVvwedroM6nqZBB4mi1+T0dZn4qsNkG4D0w7IE7MTRgyyYARqrGEq5yOFwIDAQABn-----END PUBLIC KEY-----"""

再次阅读PyJWT安装指南后,似乎对于某些签名算法,如RSA,需要安装python密码库。

我通过安装dependency:解决了这个问题

pip install pyjwt[crypto]

我也遇到了同样的问题(Mac上的Python版本3.6.7),但解决方案完全不同,除了一些其他步骤外,我还通过提供的答案解决了这个问题。

注意:不要认为,如果您激活了虚拟环境并使其长期处于活动状态,它将以与我们期望的相同的效率工作。因此,即使你的电脑、笔记本电脑、系统等处于睡眠模式,也要确保重新激活它。

看看下面我到底面对了什么,并最终解决了这个问题。

我是如何生成Private&公钥

下面是要执行的两个命令,以获得private&公钥。

> openssl genrsa -out jwt-key 4096
> openssl rsa -in jwt-key -pubout > jwt-key.pub

获取JWT(编码)

encoded_jwt = jwt.encode({ "user_id": 1 }, private_key, algorithm='RS256')

它在不同虚拟环境的项目中取得了成功。现在,我试图在另一个具有不同虚拟环境的项目中解码这个JWT(该项目几天前已经激活,并且仍然处于活动状态)。

payload = jwt.decode(encoded_jwt, public_key, algorithms=['RS256'])

并看到了此错误/异常消息。

3.6/site-packages/jwt/api_jws.py", line 226, in _verify_signature
raise InvalidAlgorithmError('Algorithm not supported')
jwt.exceptions.InvalidAlgorithmError: Algorithm not supported

哎呀!让我们试着解决它!

我是如何解决的

在阅读了答案后,我按照步骤在我已经激活的虚拟环境中安装了pyjwt[crypto]cryptography(任何一个)包,但我的问题也没有得到解决。这让我考虑尝试另一种算法,但我想尝试并集思广益寻找其他解决方案。

我只是查看了<virtualenv_dir>/lib/site-packages/内部,发现没有安装cryptography包,而是在实际的Python环境中安装在外部。

因此,现在,我有了一些解决问题的想法,并执行了以下步骤来解决问题。

  1. 已停用虚拟环境
  2. 运行pip uninstall pyjwt[crypto]
  3. 运行pip uninstall cryptography
  4. 激活虚拟环境
  5. 运行pip install pyjwt[crypto]
  6. 运行pip install cryptography

现在,当我解码编码的JWT时,它工作得很好。

解码JWT

> payload = jwt.decode(encoded_jwt, public_key, algorithms=['RS256'])`
> payload
{ "user_id": 1 }

最后,这个错误得到了解决。

这里解释了发生错误的原因。你可以解决这个问题,只需避免检查jwt:的受众数据

import jwt
ALGORITHM = "HS256"
options={
'verify_exp': False,  # Skipping expiration date check
'verify_aud': False 
}
try:
payload = jwt.decode(token, YOUR_SECRET_KEY, algorithms=[ALGORITHM], options=options)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))

相关内容

最新更新