【问题标题】:Verifying JWT (RS256) using OpenSSL使用 OpenSSL 验证 JWT (RS256)
【发布时间】:2021-07-12 14:40:50
【问题描述】:

我的要求是使用公钥 (RS256) 验证 JWT。检查应仅基于本机 OpenSSL。

我使用JWT.IO 初始内容进行测试。此令牌已生成:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA P>

当我输入 Header + Payload + Signature(下图中的项目 1 和 2)时,它们之间有点。接下来,我输入一个公钥(图片中的第 3 项)。 As result I see message ‘Signature verified’ (item 4 in the picture).

现在我想使用 OpenSSL 获得相同的结果。

我已经执行了步骤:

  1. 创建文本文件 /tmp/pub.pem 并将以下内容粘贴到其中(从 JWT.IO 测试用例复制):

-----开始公钥----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0 e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9 MWIDAQAB -----结束公钥-----

  1. 创建文本文件数据 /tmp/data.txt 并将以下内容粘贴到其中。这是由点分隔的 Header 和 Payload(图片中的第 1 项):

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0

  1. 创建文本文件数据 /tmp/signature.txt 并将以下内容粘贴到其中(这是图片中的第 2 项):

POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA P>

  1. 我运行 OpenSSL 命令:

    openssl dgst -verify /tmp/pub.pem -keyform PEM -sha256 -signature /tmp/signature.txt -binary /tmp/data.txt
    

    但是得到结果:

    验证失败。

我到底做错了什么?

【问题讨论】:

  • 我撤回了 closevote,因为我意识到建议的 dup 目标并没有完全回答这个问题,因为 JWT 的签名是 base64url 编码的,而 openssl 不能直接处理 base64url。

标签: openssl jwt base64 jwt.io


【解决方案1】:

JWT 的签名是 base64url 编码的,需要先解码。 suggested duplicate 仅处理 base64 编码的签名,而 openssl 似乎不适用于 base64url 编码。

如果你在Windows系统上工作,可以用certutil解码签名文件,可以直接解码bas64url:

certutil -decode signature.txt signature.sha256

然后使用 signature.sha256 作为 openssl 的输入:

openssl.exe dgst -sha256 -verify pubkey.pem -signature signature.sha256 data.txt

那么你应该得到结果:

验证正常

【讨论】:

  • 不幸的是它不起作用。此命令certutil -decode signature.txt signature.sha256 创建了长度为 256 字节的新文件 signature.sha256。没关系。但是验证命令openssl.exe dgst -sha256 -verify pubkey.pem -signature signature.sha256 data.txt返回结果验证失败
  • 是的,openssl 无法解码 base64url,这就是我写答案的原因。请再次检查您的文件是否正常。我在写答案之前检查了它,我又检查了一遍,并得到了验证。我使用了您问题中的所有数据。特别是。公钥文件的格式应正确,在 64 个字符后有换行符,页眉和页脚在单独的行中。
  • 我还尝试运行命令openssl enc -d -A -base64 -in signature.txt -out signature.sha1,结果创建了文件signature.sha1。但是这个文件的长度为 0 字节(似乎是无效文件)。当我运行验证命令时,它返回 Error reading signature file signature.sha1
  • 您之前已经发布过该评论。是的,我也看到结果是0字节,当然会有错误(因为文件是空的!)。请再次阅读我上面的评论。在我写答案之前,我实际上测试了这些命令,它确实有效。也许其中一个文件中存在一些复制/粘贴错误、缺少字符或其他原因?
  • 是的,非常感谢!我已经删除了所有早期文件并重复了所有步骤。我不知道为什么上次失败了,但现在你对命令certutil -decode signature.txt signature.sha256 的回答解决了这个问题。验证成功。再次感谢您!
猜你喜欢
  • 2021-05-10
  • 2018-11-25
  • 2018-08-06
  • 2020-12-08
  • 2019-04-06
  • 2021-03-02
  • 2017-09-23
  • 2020-09-25
  • 2017-08-12
相关资源
最近更新 更多