エラーメッセージ
Invalid crypto padding
別の表記
- Invalid header padding
- Invalid payload padding
- jwt.exceptions.DecodeError: Invalid crypto padding
「padding」の前の単語がセグメントを示します。`header`、`payload`、`crypto`(署名)のいずれかです。
PyJWT (Python) — jwt.exceptions.DecodeError while base64url-decoding a segment
このエラーの意味
PyJWT はトークンを 3 つのセグメントに分割しましたが、そのうちの 1 つを base64url デコードできませんでした。「crypto padding」は 3 番目(署名)のセグメントを、「header padding」と「payload padding」はそれぞれ 1 番目と 2 番目のセグメントを指します。JWS のセグメントは、`=` のパディングなしで、URL セーフな base64 のアルファベット(`A–Z a–z 0–9 - _`)を使わなければなりません。スペース、`+`、`/`、または長さの誤りがあると、署名のチェックより前にデコードが失敗します。
発生する理由
Bearer プレフィックスが付いたままになっている
よくある`"Bearer eyJ…"` を渡すと、ヘッダーのセグメントにスペースと Bearer という単語が入り、「Invalid header padding」で失敗します。
トークンの生成側が標準の base64 を使っている
よくあるURL セーフな版ではなく `base64.b64encode` を使う自作の署名処理や、`=` のパディングを残す署名処理は、`+`、`/`、`=` を含むセグメントを生成します。これが最もよく影響するのは署名のセグメントで、その場合は「Invalid crypto padding」になります。
トークンが途中で URL エンコードまたはデコードされた
ときどきクエリ文字列やフォームのフィールドで渡されたトークンは、`%2B`/`%3D` のシーケンスを含んだまま届いたり、フォームのデコーダーによって `+` がスペースに変換されたりすることがあります。
コピーの際に文字が追加された、または失われた
ときどきターミナルからの改行、JSON の引用符、ログビューアーが挿入した省略記号によって、セグメントの長さとアルファベットが変わります。
修正方法
- 1.
スキームを取り除き、アルファベットを検証する
トークンが base64url の JWS のパターンに一致する `Bearer <token>` だけを受け入れ、それ以外はすべて、PyJWT を呼び出す前に 401 を返してください。
python import re BASE64URL_JWS = re.compile(r"^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$") def extract(authorization: str) -> str: scheme, _, token = authorization.partition(" ") token = token.strip() if scheme.lower() != "bearer" or not BASE64URL_JWS.match(token): raise ValueError("not a compact JWS") return token - 2.
パディングなしの base64url でエンコードする
トークンを自分で組み立てる場合は、URL セーフな base64 を使い、末尾の `=` を削除してください。さらに良いのは、JOSE ライブラリにトークンを組み立てさせることです。
python import base64 def b64url(data: bytes) -> str: # JWS uses base64url WITHOUT padding (RFC 7515 section 2). return base64.urlsafe_b64encode(data).rstrip(b"=").decode("ascii")