解密签名和验证 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;
我知道还有其他库可以让我更轻松地使用 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;