0
0

More than 1 year has passed since last update.

(Cognito/Lambda)JWTをBase64でデコードしたときのエラー``` Error: Incorrect padding ```の解決策

Posted at

はじめに

Cognitoでログイン画面を実装し、そのログイン情報をlambdaなどで処理する際にJWT(Json Web Token)をデコードして使用するだろう。
基本的にはBase64+jsonでデコード可能なのだが、一部ハマるポイントがある。

事象

処理できる文字列と処理できない文字列が存在した。

問題が起こったコードとその挙動

import base64

# JWTを"."で分割して、ヘッダ、ペイロード、署名に分ける
header, payload, signature = jwt_string.split(".")

# ヘッダとペイロードをデコード
decoded_header = base64.b64decode(header).decode("utf-8")
decoded_payload = base64.b64decode(payload).decode("utf-8")

# ヘッダ、ペイロード、署名を表示
print("Header: ", decoded_header)
print("Payload: ", decoded_payload)
print("Signature: ", signature)
(例)ログイン情報
ユーザID:test_111
 →(JWT)eyJvcmlnaW5fanRpIjoiOG5fanRpIjoiOG5fanRpIjoiOG~~~
 →(デコード)ユーザID:test_111

ユーザID:test_AAA
 →(JWT)eyJvcmlnaW5fanRpIjoiOG5fanRpIjoiOG5fanRpIjoiOG~~~
 →(デコード)エラー:Error: Incorrect padding 

通常のBase64エンコードでは対応できない

早速調べたら、下記のような記事を発見した。4で割れるように文字列を=で調整しなさいということだ。

base64_str += "=" * ((4 - len(base64_str) % 4) % 4)        

原因

根本的な原因はJETがURL-safeという仕様だから。
通常のBase64エンコードでは+/を意識せずに変換しますが、それらの記号はURL上では特別な意味をもってしまうため、それも別な文字に置き換える必要がある。

+ を - に置換
/ を _ に置換

解決策

Base64 URL Encodeを使用するのが無難であろう。ただ、確実性と可読性からpython-joseライブラリを使用して問題解決した。
レイヤーを追加する手間はあるが、改ざんも発見可能で日本語の難しい漢字も確実にデコードしてくれるのでこちらを使用する。

レイヤーを追加する場合のコマンド

$ mkdir python
$ pip3 install -t python python-jose
$ zip -r9 layer.zip python

参考:https://sebenkyo.com/2021/05/21/post-1979/

修正したコード

jwt_str = response['AuthenticationResult']['IdToken']
# python-joseでidtokenをdecode
payload = jwt.get_unverified_claims(jwt_str)
# 結果をコンソールに表示
print(payload)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0