使用 OpenSSL 验证 JWT (RS256)

问题描述

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

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

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA

当我输入 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 并将以下内容粘贴到其中。这是由点分隔的标题和有效载荷(图片中的第 1 项):

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUyxN

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

POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA

  1. 我运行 OpenSSL 命令:

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

    但是得到结果:

    验证失败。

我到底做错了什么?

解决方法

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

那么你应该得到结果:

验证正常

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...