问题描述
我的要求是使用公钥 (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 获得相同的结果。
我已经执行了步骤:
- 创建文本文件 /tmp/pub.pem 并将以下内容粘贴到其中(从 JWT.IO 测试用例复制):
-----开始公开密钥----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0 e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9 MwIDAQAB -----结束公钥-----
- 创建文本文件数据 /tmp/data.txt 并将以下内容粘贴到其中。这是由点分隔的标题和有效载荷(图片中的第 1 项):
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUyxN
- 创建文本文件数据 /tmp/signature.txt 并将以下内容粘贴到其中(这是图片中的第 2 项):
POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA
-
我运行 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
那么你应该得到结果:
验证正常