python - 与示例 JWT 相比,获得不正确的 HMAC SHA256 签名
问题描述
我正在尝试遵循 [RFC for JSON Web Signatures]1,但在遵循示例时遇到了一些问题。
我把一切都搞定了,我无法生成相同的签名。以下是 Python 3.8 代码示例:
import hmac
import hashlib
import base64
signing_input = b"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
key = b"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
signature = hmac.digest(key, signing_input, digest=hashlib.sha256)
print(base64.urlsafe_b64encode(signature))
# Output: b'ZekyXWlxvuCN9H8cuDrZfaRa3pMJhHpv6QKFdUqXbLc='
# Expected: b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
此外,我尝试了一些处理 HMAC-SHA256 的在线工具,但我得到的输出与我的 Python 脚本提供的输出相同。关于我哪里出错的任何想法?[1]:https ://www.rfc-editor.org/rfc/rfc7515#appendix-A.1
解决方案
您使用了错误的密钥。RFC使用JSON Web Algorithm以JSON Web Key格式显示密钥。这意味着密钥是一个 base64url 编码的字节序列。如果您希望结果匹配,您需要在使用它之前对其进行解码。 "oct"
请注意,pythonurlsafe_b64decode
并urlsafe_b64encode
没有完全实现 JWT 和朋友使用的 base64url 编码。python 函数期望/产生填充字符,JWT 使用的 base64url 编码指定的应该被删除。
把这一切放在一起:
import hmac
import hashlib
import base64
signing_input = b"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
key = b"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
# Decode the key. Pad it with '=' characters to a length divisible by 4
# as expected by urlsafe_b64decode
if len(key) % 4 == 2:
key += b'=='
elif len(key) % 4 == 3:
key += b'='
key = base64.urlsafe_b64decode(key)
signature = hmac.digest(key, signing_input, digest=hashlib.sha256)
signature = base64.urlsafe_b64encode(signature)
# Strip off any '=' characters urlsafe_b64encode added to pad the key to
# a length divisible by 4
signature = signature.rstrip(b'=')
print(signature)
# Prints: b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
推荐阅读
- sed - 如何在另一个文件中用 HTML 实体替换 UTF-8 字符?
- python - 新手问题 - 将函数分成两部分
- python - Pytest:在 setup_method 中使用固定装置
- python - 在 Python 中使用用户输入结束循环
- javascript - “m 未定义” discord.js 消息收集器
- swift - 抓取保存在 Firebase 中的数据并将其呈现在视图控制器上
- php - PHP XSLTProcessor 去除样式属性和标签
- java - 渲染后敌人的消失(Java 游戏)
- python - 训练和测试准确度图显示奇怪的行为
- python - Pandas:将数据框填充到最大行长