如何使用在线工具手动验证JWT签名

skp*_*rin 5 jwt

根据我的理解,验证JWT签名是一个直接的过程.但是,当我使用一些在线工具为我做这件事时,它并不匹配.如何在JWT不使用JWT库的情况下手动验证签名?我需要一种快速方法(使用可用的在线工具)来演示如何完成此操作.

JWThttps://jwt.io/#debugger-io上创建了我的以下信息:

  • 算法: HS256
  • 秘密: hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
  • 标题:
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  • 有效载荷:
    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }
    
  • 验证签名(部分):
    • 秘密值改为上面
    • "已检查"秘密base64编码(无论是否检查,仍然获得不同的值)

智威汤逊:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.wDQ2mU5n89f2HsHm1dluHGNebbXeNr748yJ9kUNDNCA

手动JWT签名验证尝试:

使用base64UrlEncode计算器(http://www.simplycalc.com/base64url-encode.phphttps://www.base64encode.org/)

如果我:( 不是站点上的实际值,修改后显示最终为我构建的工具)

base64UrlEncode("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9") + "." + base64UrlEncode("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ")

我明白了:

ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5.ZXlKemRXSWlPaUl4TWpNME5UWTNPRGt3SWl3aWJtRnRaU0k2SWtwdmFHNGdSRzlsSWl3aWFXRjBJam94TlRFMk1qTTVNREl5ZlE=

注意:如果我应该对已经编码的值进行编码,或者按原样使用已经编码的值,那么我会有一些困惑.

(即使用base64UrlEncode("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9") + "." + base64UrlEncode("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ")vs "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ").

无论我应该做什么,最终结果仍然与签名不符.我倾向于认为我应该重新编码的编码值,不管是真还是假.

然后使用HMAC Generator计算器(https://codebeautify.org/hmac-generatorhttps://www.freeformatter.com/hmac-generator.html#ad-output)

(不是网站上的实际价值,经过修改以显示最终为我构建的工具)

HMACSHA256(
 "ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5.ZXlKemRXSWlPaUl4TWpNME5UWTNPRGt3SWl3aWJtRnRaU0k2SWtwdmFHNGdSRzlsSWl3aWFXRjBJam94TlRFMk1qTTVNREl5ZlE=",
  "hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6"
)

哪个让我:

a2de322575675ba19ec272e83634755d4c3c2cd74e9e23c8e4c45e1683536e01

这与以下标志部分不符JWT:

wDQ2mU5n89f2HsHm1dluHGNebbXeNr748yJ9kUNDNCAM != a2de322575675ba19ec272e83634755d4c3c2cd74e9e23c8e4c45e1683536e01


目的:

我需要确认这一点的原因是为了证明能够验证JWT没有被篡改,而不解码JWT.

我的客户端Web界面不需要解码JWT,所以他们不需要安装jwt包来执行此操作.他们只需要进行简单的验证,以确认在JWT存储JWT未来的API调用之前没有被篡改(但不太可能).

jps*_*jps 6

这都是格式和编码的问题.

https://jwt.io上,您可以根据输入值和密码获取此令牌:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
Run Code Online (Sandbox Code Playgroud)

我们要证明签名:

3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
Run Code Online (Sandbox Code Playgroud)

是正确的.

签名是Base64url编码的HMAC-SHA256哈希.(如RFC7515中所述)

当您使用在线HMAC生成器计算哈希值时

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Run Code Online (Sandbox Code Playgroud)

随着秘密

hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
Run Code Online (Sandbox Code Playgroud)

你得到

de921a2a4b225fd66ff0983e8566eb0f6e1584bdfa84120568da40e1f571dbd3
Run Code Online (Sandbox Code Playgroud)

结果,这是一个HMAC-SHA256值,但不是Base64url编码的.此哈希是十六进制数的ASCII表示.

要将其与https://jwt.io中的值进行比较,您需要转换其ASCII十六进制表示值并对其进行Base64url编码.

以下脚本正在执行此操作,并使用crypto-js来计算它自己的哈希值.这也可以让您在没有JWT库的情况下进行验证.

var CryptoJS = require("crypto-js");

// the input values
var base64Header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
var base64Payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ";
var secret = "hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6";

// two hashes from different online tools
var signatureJWTIO = "3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M";
var onlineCaluclatedHS256 =  "de921a2a4b225fd66ff0983e8566eb0f6e1584bdfa84120568da40e1f571dbd3";

// hash calculation with Crypto-JS. 
// The two replace expressions convert Base64 to Base64url format by replacing '+' with '-' 
// and stripping the '=' padding
var base64Signature = CryptoJS.HmacSHA256(base64Header + "." + base64Payload , secret).toString(CryptoJS.enc.Base64).replace(/\+/g,'-').replace(/\=+$/m,'');

// converting the online calculated value to Base64 representation
var base64hash = new Buffer(onlineCaluclatedHS256, 'hex').toString('base64').replace(/\+/g,'-').replace(/\=+$/m,'');


// the results:
console.log("Signature from JWT.IO             : " + signatureJWTIO);
console.log("NodeJS calculated hash            : " + base64Signature);
console.log("online calulated hash (converted) : " + base64hash);
Run Code Online (Sandbox Code Playgroud)

结果是:

Signature from JWT.IO             : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M

NodeJS calculated hash            : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M

online calulated hash (converted) : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
Run Code Online (Sandbox Code Playgroud)

相同!

结论:

由不同的格式和编码,由不同的在线工具计算的值都是正确的,但不能直接比较.如上所示的小脚本可能是更好的解决方案.


小智 5

我遇到了同样的问题,直到我发现我使用的是纯base64编码而不是base64url。\n之间还有一些小细节。\n这里是分步手册,希望能够使整个过程更加清晰。

\n\n

笔记

\n\n

注意 1:您必须从 JSON 字符串(标头和负载)中删除所有空格和换行符。\n当您生成 JWT 令牌时,它会在jwt.io上隐式完成。

\n\n

注 2:要将 JSON 字符串转换为base64urlcryptii.com 上的字符串,请创建以下配置:

\n\n
First view: Text\n\nSecond view: Encode\n    Encoding: Base64\n    Variant: Standard \'base64url\' (RFC 4648 \xc2\xa75)\n\nThird view: Text\n
Run Code Online (Sandbox Code Playgroud)\n\n

注 3:要将 HMAC HEX 代码(签名)转换为base64urlcryptii.com 上的字符串,请创建以下配置:

\n\n
First view: Bytes\n    Format: Hexadecimal\n    Group by: None\n\nSecond view: Encode\n    Encoding: Base64\n    Variant: Standard \'base64url\' (RFC 4648 \xc2\xa75)\n\nThird view: Text\n
Run Code Online (Sandbox Code Playgroud)\n\n

手动的

\n\n

您只需要两个在线工具:

\n\n
    \n
  1. [工具1]: cryptii.com - 用于base64url编码,
  2. \n
  3. [工具2]: codebeautify.org - 用于HMAC计算。
  4. \n
\n\n

cryptii.com上,您既可以进行编码/解码,也可以进行 HMAC 计算,但是对于 HMAC,您需要提供与jwt.iobase64url上的输入不同的十六进制密钥,因此我使用单独的服务进行 HMAC 计算。

\n\n

输入数据

\n\n

在本手册中我使用了以下数据:

\n\n\n\n

秘密没有base64被编码。

\n\n

第1步:转换标头【工具1】

\n\n\n\n

步骤2:转换有效负载[工具1]

\n\n\n\n

第三步:计算HMAC码(签名)【工具2】

\n\n

使用算法计算HMAC SHA256

\n\n\n\n

计算出的 HMAC 代码是签名的十六进制表示。\n注意:不应将其编码为base64url纯文本字符串,而应编码为字节序列。

\n\n

第四步:将计算出的HMAC代码编码到base64url【工具1】中:

\n\n\n\n

概括

\n\n

这是我们的结果(全部base64url编码):

\n\n\n\n

jwt.io的结果:

\n\n
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.yKmuWfPWRWQ2SoZNIkkMxmbHTGajgivgSpqSh6cHs1I\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,所有三个部分都是相同的。

\n