PyJWT加密参数的作用是什么?如何加密保护存储敏感数据的JWT令牌?
关于JWT使用的常见疑问解答
1. 你当前使用的JWS(签名JWT)的密钥作用
你之前的猜测是正确的,你当前使用HS256算法生成的是JWS(JSON Web 签名令牌),并非加密令牌:
- JWS由header、payload、signature三部分组成,前两部分仅做了Base64Url编码,没有任何加密逻辑,任何人拿到令牌都可以直接解码获取内容
- 你设置的
my-super-secret-key仅用来生成第三部分的签名,核心作用是校验令牌是否被篡改:只有持有密钥的一方可以验证签名合法性,避免攻击者修改payload内容(比如篡改用户权限)后伪造合法令牌
2. 常规JWS适合存储的内容
常规JWS场景下绝对不能存储明文敏感数据,若邮箱、用户名属于你业务中的敏感信息,也不建议直接放在JWS的payload中。JWS仅适合存储非敏感的标识类信息,比如用户ID、公开的权限标识等。
3. 加密保护JWT内容的方案:JWE
JWE(JSON Web 加密)是专门解决敏感信息存储需求的JWT规范,它是真正对payload做了加密处理的方案,没有解密密钥的人拿到令牌也无法读取payload内容,逻辑非常简洁:
- 相比JWS多了密钥协商、内容加密的步骤,最终输出的令牌payload为密文,无法直接解码读取
- pyjwt本身不直接支持JWE,你可以换用
jwcrypto库实现JWE的生成和解析,极简示例如下:
from jwcrypto import jwk, jwe import json # 生成加密密钥,也可提前生成后持久化存储 key = jwk.JWK.generate(kty='oct', size=256) # 待加密的载荷内容 payload = json.dumps({ "user": {"email": "xxx@example.com", "username": "test"}, "exp": 1630301228 }) # 生成JWE加密令牌 jwe_token = jwe.JWE(payload, protected={"alg": "A256KW", "enc": "A256GCM"}) jwe_token.add_recipient(key) encrypted_token = jwe_token.serialize(compact=True) # 解密读取令牌内容 decrypted_jwe = jwe.JWE() decrypted_jwe.deserialize(encrypted_token, key=key) decrypted_data = json.loads(decrypted_jwe.payload)
4. 低成本替代方案
如果觉得JWE实现复杂度较高,也可以选择两种更简单的方案:
- 仅在JWT中存储用户ID,敏感数据每次需要时从数据库/缓存中查询,这是业内最常用、安全性最高的方案
- 先自行对敏感数据做对称加密,把加密后的密文放到JWS的payload中,效果和JWE类似,仅需自己实现加解密逻辑即可
内容的提问来源于stack exchange,提问作者lccmrx
相关产品推荐
相关产品推荐

