如何使用在线工具手动验证JWT签名 [英] How to manually validate a JWT signature using online tools

查看:232
本文介绍了如何使用在线工具手动验证JWT签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

From what I can understand, it's a straight forward process to validate a JWT signature. But when I use some online tools to do this for me, it doesn't match. How can I manually validate a JWT signature without using a JWT library? I'm needing a quick method (using available online tools) to demo how this is done.

我在 https://jwt.io/#debugger-io 上创建了JWT带有以下信息:

I created my JWT on https://jwt.io/#debugger-io with the below info:

  • 算法: HS256
  • 秘密: hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
  • 标题:
  • Algorithm: HS256
  • Secret: hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
  • Header:

{
  "alg": "HS256",
  "typ": "JWT"
}

  • 有效载荷:

    
    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }
    

  • 验证签名(部分):
    • 秘密值更改为上方
    • 已检查"秘密base64编码(无论是否已检查,仍会获得不同的值)
    • Verify Signature (section):
      • Secret value changed to above
      • "Checked" secret base64 encoded (whether this is checked or not, still get a different value)
      • JWT:

        
        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.wDQ2mU5n89f2HsHm1dluHGNebbXeNr748yJ9kUNDNCA
        


        手动JWT签名验证尝试:


        Manual JWT signature verification attempt:

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

        如果我: (不是网站上的实际价值,请修改以显示该工具最终为我构建的内容)

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

        我得到:

        
        ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5.ZXlKemRXSWlPaUl4TWpNME5UWTNPRGt3SWl3aWJtRnRaU0k2SWtwdmFHNGdSRzlsSWl3aWFXRjBJam94TlRFMk1qTTVNREl5ZlE=
        

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

        NOTE: there's some confusion on my part if I should be encoding the already encoded values, or use the already encoded values as-is.

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

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

        Regardless on which I should do, the end result still doesn't match the signature. I'm leaning towards that I should NOT re-encode the encoded value, whether that's true or not.

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

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

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

        哪个会吸引我:

        
        a2de322575675ba19ec272e83634755d4c3c2cd74e9e23c8e4c45e1683536e01
        

        JWT的签名部分不匹配:

        wDQ2mU5n89f2HsHm1dluHGNebbXeNr748yJ9kUNDNCAM != a2de322575675ba19ec272e83634755d4c3c2cd74e9e23c8e4c45e1683536e01

        目的:

        我需要确认这一点的原因是为了证明无需解码JWT即可验证JWT未被篡改的能力.

        The reason I'm needing to confirm this is to prove the ability to validate that the JWT hasn't been tampered with, without decoding the JWT.

        我的客户的Web界面不需要解码JWT,因此不需要他们安装 jwt软件包.他们只需要做一个简单的验证就可以确认JWT未被篡改(但是不太可能被篡改),然后再存储JWT供以后的API调用.

        My clients web interface doesn't need to decode the JWT, so there's no need for them to install a jwt package for doing that. They just need to do a simple validation to confirm the JWT hasn't been tampered with (however unlikely that may be) before they store the JWT for future API calls.

        推荐答案

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

        It's all a matter of formats and encoding.

        https://jwt.io 上,您会根据您的输入值和密码获得此令牌:

        On https://jwt.io you get this token based on your input values and secret:

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
        

        我们要证明签名:

        3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
        

        是正确的.

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

        The signature is a HMAC-SHA256 hash that is Base64url encoded. (as described in RFC7515)

        使用在线HMAC生成器来计算哈希值时为

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
        

        秘密

        hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
        

        您得到

        de921a2a4b225fd66ff0983e8566eb0f6e1584bdfa84120568da40e1f571dbd3
        

        结果为

        ,它是HMAC-SHA256值,但不是Base64url编码的.该哈希是大量的十六进制字符串表示形式.

        as result, which is a HMAC-SHA256 value, but not Base64url encoded. This hash is a hexadecimal string representation of a large number.

        要将其与 https://jwt.io 中的值进行比较,您需要将其值转换为十六进制字符串表示形式返回一个数字,然后Base64url对其进行编码.

        To compare it with the value from https://jwt.io you need to convert the value from it's hexadecimal string representation back to a number and Base64url encode it.

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

        The following script is doing that and also uses crypto-js to calculate it's own hash. This can also be a way for you to verify without JWT libraries.

        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);
        

        结果是:

        Signature from JWT.IO             : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
        
        NodeJS calculated hash            : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
        
        online calulated hash (converted) : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
        

        完全相同!

        结论:

        由不同的在线工具计算出的值都是正确的,但由于格式和编码不同,因此无法直接进行比较. 上面显示的一个小脚本可能是一个更好的解决方案.

        The values calculated by the different online tools are all correct but not directly comparable due to different formats and encodings. A little script as shown above might be a better solution.

        这篇关于如何使用在线工具手动验证JWT签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆