You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅使用hashlib库验证RS256算法的JWT令牌问题求助

手动验证AWS JWT的问题解决方法

问题2:sig**e计算耗时极久的解决办法

直接用Python内置的pow函数三参数形式:pow(sig, e, n)。这是模幂运算,底层用了高效的快速幂算法,避免了直接计算超大数幂导致的内存和时间爆炸,几毫秒就能完成计算,完全不会出现长时间无结果的情况。

原理:RSA验证的核心是计算 sig^e mod n,Python的pow(base, exp, mod)专门针对该场景优化,跳过了生成天文数字的中间步骤。

问题1:padded_hashed_ph结果不合理的排查与修正

你需要严格遵循RSA PKCS#1 v1.5填充规则(RS256等RSA签名算法默认使用该填充),同时确保每一步编码/解码无错误,步骤如下:

1. 正确解码JWT签名部分

JWT签名采用Base64URL编码,解码前需先做格式转换:

  • 将签名中的-替换为+,_替换为/
  • 补全Base64填充:按每4个字符一组补=(如长度模4余1补3个=,余2补2个,余3补1个)
  • 用base64.b64decode()解码为二进制字节,再转成整数sig:int.from_bytes(decoded_sig, byteorder='big')

2. 正确计算头部+载荷的哈希

  • 取JWT拆分后的前两部分:header_str + '.' + payload_str,用UTF-8编码为字节:data = f"{header}.{payload}".encode('utf-8')
  • 根据JWK的alg字段选择哈希算法:比如RS256对应SHA-256,用hashlib.sha256(data).digest()得到哈希字节

3. 执行PKCS#1 v1.5填充

填充后的字节长度需与RSA模数n的字节长度一致(如2048位的n对应256字节),填充规则为:
0x00 + 0x01 + [0xFF * k] + 0x00 + ASN.1_DER_PREFIX + 哈希值
其中:

  • k为填充的0xFF数量,需满足总长度等于模数字节长度
  • SHA-256的ASN.1 DER前缀为固定字节串:b'\x30\x31\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'

示例代码(假设模数为256字节):

import hashlib
import base64

# 假设已获取header_str, payload_str, sig_b64url, e, n(e和n为JWK中转换后的整数)
data = f"{header_str}.{payload_str}".encode('utf-8')
hash_bytes = hashlib.sha256(data).digest()

# SHA-256的ASN.1 DER前缀
der_prefix = b'\x30\x31\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
encoded_hash = der_prefix + hash_bytes

# 计算填充长度
modulus_bytes_length = (n.bit_length() + 7) // 8
padding_length = modulus_bytes_length - len(encoded_hash) - 2  # 减去0x00和0x01的长度

# 构造填充后的字节
padded_bytes = b'\x00\x01' + (b'\xFF' * padding_length) + b'\x00' + encoded_hash

# 转成整数
padded_hashed_ph = int.from_bytes(padded_bytes, byteorder='big')

4. 对比验证

用pow(sig, e, n)得到结果,与padded_hashed_ph对比,若相等则签名验证通过。


内容的提问来源于stack exchange,提问作者Jamie Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:27:32