Python解码JWT报错jwt.exceptions.DecodeError: Invalid crypto padding如何解决
报错原因
该错误的根源是你使用的JWT签名段的Base64URL编码缺少标准要求的补位字符=。Python标准库的base64.urlsafe_b64decode方法要求输入的编码长度必须为4的倍数,长度不匹配时就会抛出补位错误;而jwt.io这类工具内部实现了自动补全缺失补位符的逻辑,所以可以正常解码。
即便你关闭了签名验证,PyJWT的内部逻辑仍然会尝试解码JWT的三个分段(头部、载荷、签名),所以签名段的Base64补位问题仍然会触发解码失败。
可行解决方案
- 方案1:手动给JWT补全Base64URL补位字符后再解码,通用代码示例如下:
import jwt def fix_jwt_base64_padding(encoded_jwt: str) -> str: segments = encoded_jwt.split(".") fixed_segments = [] for seg in segments: # 计算需要补充的补位符数量 padding_len = 4 - len(seg) % 4 if padding_len != 4: seg += "=" * padding_len fixed_segments.append(seg) return ".".join(fixed_segments) def main(args): encoded_jwt = "eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLm1kbC5lbnRlcmN5IiwiZXhwIjoxNjI3MzgyMTI3LCJpYXQiOjE2MjcyOTU3MjcsInN1YiI6IjAwMTUxMC5hNjQ0MzcyOWE3OTU0ZmQyYTE2NjcyN2NjODY0ZDUyZi4wODI4IiwiY19oYXNoIjoiVl9yUG1Db1Vab0lmejlJQW9WcEFNZyIsImVtYWlsIjoiZnJlZGVyaWNrLm1kbEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJhdXRoX3RpbWUiOjE2MjcyOTU3MjcsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.DDc3G6jJbsLXYX_F3GQ851mEukVDAMvySDPWwWfsmQOmi8w_ItCUaMwSMp0djzzFy3dLpF2cMp67n" # 先补位再解码 fixed_jwt = fix_jwt_base64_padding(encoded_jwt) val = jwt.decode(fixed_jwt, options={"verify_signature": False}) print(val) return if __name__ == '__main__': main(0)
- 方案2:如果完全不需要处理签名,也可以直接拆分JWT的头部和载荷段单独解码,跳过签名段的解析:
import base64 import json encoded_jwt = "eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLm1kbC5lbnRlcmN5IiwiZXhwIjoxNjI3MzgyMTI3LCJpYXQiOjE2MjcyOTU3MjcsInN1YiI6IjAwMTUxMC5hNjQ0MzcyOWE3OTU0ZmQyYTE2NjcyN2NjODY0ZDUyZi4wODI4IiwiY19oYXNoIjoiVl9yUG1Db1Vab0lmejlJQW9WcEFNZyIsImVtYWlsIjoiZnJlZGVyaWNrLm1kbEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJhdXRoX3RpbWUiOjE2MjcyOTU3MjcsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.DDc3G6jJbsLXYX_F3GQ851mEukVDAMvySDPWwWfsmQOmi8w_ItCUaMwSMp0djzzFy3dLpF2cMp67n" header_enc, payload_enc, _ = encoded_jwt.split(".") # 补全补位符后解码 header = json.loads(base64.urlsafe_b64decode(header_enc + "=" * (4 - len(header_enc) % 4))) payload = json.loads(base64.urlsafe_b64decode(payload_enc + "=" * (4 - len(payload_enc) % 4))) print(header) print(payload)
内容的提问来源于stack exchange,提问作者Mixalis Navridis
相关产品推荐
相关产品推荐

