跳到主要内容
ecdsa.com
PyJWT (Python)JWT 库

错误信息

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 - _`),并且不带 `=` 填充;空格、`+`、`/` 或长度不对,都会让解码在任何签名检查之前就失败。

原因

修复方法

  1. 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. 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")

相关错误

浏览完整的签名错误库