解密签名和验证 JWT

Decrypting signature and Veryifying JWT

我知道还有其他库可以让我更轻松地使用 JWT(在 node.js 中)。

在这种情况下,我使用 "crypto-js" 手动学习 JWT。以下给了我令牌:

var header = {
    "alg": "HS256",
    "typ": "JWT"
};
var wordArrayHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
var base64Header = CryptoJS.enc.Base64.stringify(wordArrayHeader);

var payload = {
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true
};
var wordArrayPayload = CryptoJS.enc.Utf8.parse(JSON.stringify(payload));
var base64Payload = CryptoJS.enc.Base64.stringify(wordArrayPayload);

var signature = CryptoJS.HmacSHA256(base64Header + "." + base64Payload , "secret");
var base64Sign = CryptoJS.enc.Base64.stringify(signature);
var token = base64Header + "." + base64Payload + "." + base64Sign;

我无法执行完全相反的操作来验证令牌。例如,以下在解密签名时会引发错误:

var token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
var base64Header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
var base64Payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9";
var base64Sign = "TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";

var parsedSignArray = CryptoJS.enc.Base64.parse(base64Sign);
var parsedSign = parsedSignArray.toString(CryptoJS.enc.Utf8);
var decrypted = CryptoJS.HmacSHA256.decrypt(parsedSign , "secret");
console.log(decrypted);

我在这里错过了什么?顺便说一句,就这个例子而言,我使用的是 http://jwt.io

的令牌

没有CryptoJS.HmacSHA256.decrypt这样的东西。由于 HMAC 以及一般的哈希函数都是单向函数,因此验证 "signature" 的唯一方法是 运行 对同一字符串使用相同的单向函数,然后将其与你有一个:

var signature = CryptoJS.HmacSHA256(base64Header + "." + base64Payload , "secret").toString(CryptoJS.enc.Base64);
var valid = signature == base64Sign;