JWTトークンのデコードに pyjwt ライブラリを使用しています。デコード時にこのエラーが発生しました。コードはドキュメントに記載されています。
import jwt
encoded_jwt='''eyJ0eXAiOiJKV1QiLCJhbG......'''
secret=b''''-----BEGIN PUBLIC KEY-----
MIIFRjCCBC6gAwIBAgIQCIdSGhpikQCjOIY154XoqzANBgkqhkiG9w0BAQsFADBN
......
-----END PUBLIC KEY-----'''
print(jwt.decode(encoded_jwt, secret , algorithms=['RS256']))
raise ValueError( "キーデータをデシリアライズできませんでした。")ValueError:キーデータをデシリアライズできませんでした。
[〜#〜] jwt [〜#〜] が機能しているWebサイトでこれを使用する場合、問題を解決するのを手伝ってください。
これは完全なエラーログです。
トレースバック(最後の最新の呼び出し):ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/algorithms.py"、line 205、in prepare_key key = load_pem_private_key(key、password = None、backend = default_backend())ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/primitives/serialization.py"、20行目のload_pem_private_key return backend .load_pem_private_key(data、password)ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openends/openends/openends/openendspy/backend.py"、line 1014、in load_pem_private_key password、ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py"、1233行目、_load_key self._handle_key_loading_error()ファイル "/ home /sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py "、行1291、_handle_key_loading_error raise ValueErr or( "キーデータを逆シリアル化できませんでした。")ValueError:キーデータを逆シリアル化できませんでした。
上記の例外の処理中に、別の例外が発生しました:
トレースバック(最後の最後の呼び出し):ファイル "/home/sathiyakugan/PycharmProjects/JWTsample/sample.py"、45行目、print(jwt.decode(encoded_jwt、secret、algorithm = ['RS256']))ファイル"/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/api_jwt.py "、93行目、decode jwt、key = key、algorithms = algorithms、options = options、** kwargsファイル"/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/api_jws.py"、157行目、デコードキー、アルゴリズム)ファイル"/home/sathiyakugan/PycharmProjects/Python/venv /lib/python3.5/site-packages/jwt/api_jws.py "、行221、_verify_signature key = alg_obj.prepare_key(key)File" /home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/ site-packages/jwt/algorithms.py "、line 207、in prepare_key key = load_pem_public_key(key、backend = default_backend())File" /home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages /cryptography/hazmat/primitives/serialization.py"、24行目、load_pem_public_key内backend.load_pem_public_key(data)ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py"、line 1040、in load_pem_public_key self._handle_key_loading_error ()ファイル "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py"、line 1291、in _handle_key_loading_error raise ValueError( "Could not deserializeキーデータ。 ")ValueError:キーデータをデシリアライズできませんでした。
プロセスは終了コード1で終了しました
Pyjwtライブラリにはいくつかの問題があります。証明書から公開鍵を取得する必要があります。
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
その後、公開鍵から、authlibライブラリを使用して簡単にデコードできました。
from authlib.specs.rfc7519 import jwt
encoded_jwt='''eyJ0eXAiOiJ....'''
secret=b'''-----BEGIN PUBLIC KEY-----
......
-----END PUBLIC KEY-----'''
claims = jwt.decode(encoded_jwt, secret)
print(claims)
OpenSSLでRSAキーを作成する必要があります。
openssl genrsa -out jwt-key 4096
openssl rsa -in jwt-key -pubout > jwt-key.pub
authlib ライブラリを使用します。pyjwt
を使用してキークロークトークンをデコードできませんでした。あなたには必要だ public_key
、私はあなたがそれを持っていると思います。
from authlib.jose import jwt
key = '-----BEGIN PUBLIC KEY-----\n' + public_key + '\n-----END PUBLIC KEY-----'
key_binary = key.encode('ascii')
try:
claims = jwt.decode(encoded,key_binary)
claims.validate()
#do some logic here
#...
ProTip:エンドポイントで認証サーバー(私の場合はKeycloak)から公開鍵を簡単に取得できます。
url = 'http://localhost:8080/auth/realms/your_realm'
with urllib.request.urlopen(url) as r:
response = r.read()
public_key = json.loads(response)['public_key']
Jwtをどのようにエンコードしましたか?以下のいずれかの方法を使用します
RS256(RSA)を使用したトークンのエンコードとデコード
_encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
decoded = jwt.decode(encoded, public_key, algorithms='RS256')
_
検証なしでクレームセットを読み取る
_jwt.decode(encoded, verify=False)
{u'some': u'payload'}
_
または、同じシークレットを使用してjwtをエンコードおよびデコードします。アプローチの1つが機能するはずです。私の場合、サーバーは既に署名の検証を行っているのでjwt.decode(token, verify=False)
を使用しましたが、要求セットを取得するだけで済みます。