错误信息
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 已把令牌拆分为三段,但其中一段无法按 base64url 解码。“crypto padding”指第三段(签名段),“header padding”和“payload padding”分别指第一段和第二段。JWS 的各段必须使用 URL 安全的 base64 字母表(`A–Z a–z 0–9 - _`),并且不带 `=` 填充;空格、`+`、`/` 或长度不对,都会让解码在任何签名检查之前就失败。
原因
令牌仍带着 Bearer 前缀
常见传入 `"Bearer eyJ…"` 会把一个空格和单词 Bearer 带进头部段,随后就会报错“Invalid header padding”。
令牌生成方使用了标准 base64
常见如果手写的签名代码使用 `base64.b64encode` 而不是 URL 安全的变体,或者保留了 `=` 填充,生成的段中就会出现 `+`、`/` 或 `=`。最常受影响的是签名段,报错为“Invalid crypto padding”。
令牌在传递途中被 URL 编码或解码了
偶见通过查询字符串或表单字段传递的令牌,到达时可能带有 `%2B`/`%3D` 序列,或者其中的 `+` 已被表单解码器变成空格。
复制时多了或少了字符
偶见终端带来的换行符、JSON 中的引号,或者日志查看器插入的省略号,都会改变各段的长度和字符组成。
修复方法
- 1.
去掉认证方案前缀,并校验字母表
只接受 `Bearer <token>` 形式、且令牌部分符合 base64url JWS 模式的值;其他情况一律在调用 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")