【发布时间】:2021-06-08 18:07:26
【问题描述】:
我试图深入了解 JWT 到底是什么,所以我决定去看看规范。
第一个例子似乎成功地阻止了我继续前进。
JWT spec 中的这个示例(JWS spec 提供了更多上下文)展示了如何创建 JWT。
对于标题,它有
{
"typ":"JWT",
"alg":"HS256"
}
这是base64编码成eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9;
对于有效载荷,它有
{
"iss": "joe",
"exp": 1300819380,
"http://example.com/is_root": true
}
基于64位编码为eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
顺便说一下,我从这个post了解到,JWT中使用的based64字符串与btoa返回的并不完全相同
有问题的部分是签名。
在 JWS 中,它说该示例使用对称密钥对标头和有效负载进行签名,以 jwk 格式表示为
{
"kty": "oct",
"k": "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}
base64编码后的签名数据为dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
我试图在浏览器中重现这个例子。这是我的代码
(async () => {
const header = {
typ: "jwt",
alg: "HS256"
};
const payload = {
"iss": "joe",
"exp": 1300819380,
"http://example.com/is_root": true
};
const headerEncoded = strToSafeUrlBase64(JSON.stringify(header));
console.log('header', headerEncoded);
// prints out eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9
// Same as Example
const payloadEncoded = strToSafeUrlBase64(JSON.stringify(payload));
console.log('payload', payloadEncoded);
// prints out eyJpc3MiOiJqb2UiLCJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
// Same as Example
const _key = {
kty: "oct",
k: "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}
const HmacKeyParams = {
name: "HMAC",
hash: "SHA-256"
};
const key = await crypto.subtle.importKey(
'jwk',
_key,
HmacKeyParams,
true,
['sign', 'verify']);
const signedValue = await crypto.subtle.sign(
'HMAC', key, new TextEncoder().encode(`${headerEncoded}.${payloadEncoded}`));
console.log(uint8ToBase64(new Uint8Array(signedValue)));
// this prints out _Y6kHA7DqgEFgqbaKMMCGUwPuZMMczSXV0w34CfblCA
// not the same as the example !!
function strToSafeUrlBase64(bin) {
return btoa(bin)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+/g, '');
}
function uint8ToBase64(uint8) {
let s = '';
uint8.forEach(b => s += String.fromCharCode(b));
return strToSafeUrlBase64(s);
}
})();
我错过了什么?
我在密码学方面完全是个业余爱好者,所以不要信守诺言,用每一个残酷的事实来抨击我
【问题讨论】:
-
您的问题写得非常好,直到您遇到问题为止。我看不出你的最终代码应该如何表现以及它的实际表现如何。
标签: web encryption jwt