如何使用 Node-jose 验证 JWT 签名
How to verify a JWT signature using Node-jose
我正在尝试使用 node-jose 来验证我的 JWT 的签名。我知道秘密,但无法将此秘密转换为用于验证的 JWK。
这是一个示例,说明我如何尝试使用我的秘密创建我的密钥并验证我的令牌。这导致 Error: no key found
.
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJpYWxfbnVtYmVyIjoiNWYxMGExNjMtMjk2OC00ZDZkLWIyZDgtOGQxNjQwMDNlMmQ0Iiwic2VxIjo1MTI4MTYsIm5hbWUiOiJOYW1lMSIsImlkIjo2NTQsImRlc2NyaXB0aW9uIjoiVGVzdCBEZWNvZGluZyJ9.ahLaTEhdgonxb8rfLG6NjcIg6rqbGzcHkwwFtvb9KTE"
let secret = "SuperSecretKey"
let props = {
kid: "test-key",
alg: "HS256",
use: "sig",
k: secret,
kty: "oct"
}
let key;
jose.JWK.asKey(props).then(function(result) {key = result})
jose.JWS.createVerify(key).verify(token).then(function(result){console.log(result)})
我是否需要修改我的令牌以在某处包含 kid
header?我是否根据该库的已知秘密正确生成了密钥?
您的代码存在三个问题。
由于承诺的异步性质,key
在承诺完成时(在 .then
部分)获得一个值,但这发生在下一行之后被调用。
直接在行 jose.JWK.asKey(...
之后放置一个 console.log(key)
,您会看到结果是“未定义”。所以其实是没有钥匙的。
JWK 中的 k
值被视为 Base64Url 编码的八位字节。签署令牌时,必须使用 k
的 base64url 解码值,但不能直接使用 k
。
秘密“SuperSecretKey”对于 node.jose 来说太短了。对于 HS256 算法,密钥长度必须为 256 位。 node.jose 与其他库相比,似乎相当严格。
要解决第一个问题,您可以嵌套调用(这很快就会变得难以阅读,或者使用如下所示的 async/await 语法:
var jose = require('node-jose')
async function tokenVerifyer()
{
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJpYWxfbnVtYmVyIjoiNWYxMGExNjMtMjk2OC00ZDZkLWIyZDgtOGQxNjQwMDNlMmQ0Iiwic2VxIjo1MTI4MTYsIm5hbWUiOiJOYW1lMSIsImlkIjo2NTQsImRlc2NyaXB0aW9uIjoiVGVzdCBEZWNvZGluZyJ9.KK9F14mwi8amhsPT7ppqp_yCYwwOGcHculKByNPlDB8"
let secret = "SuperSecretKeyThatIsLongEnough!!" // A 32 character long secret to get 256 bits.
let props = {
kid: "test-key",
alg: "HS256",
use: "sig",
k: "cynZGe3BenRNOV2AY__-hwxraC9CkBoBMUdaDHgj5bQ",
//k : jose.util.base64url.encode(secret), // alternatively use above secret
kty: "oct"
}
let key = await jose.JWK.asKey(props)
let result = await jose.JWS.createVerify(key).verify(token)
}
tokenVerifyer()
在上面的示例中,k
是在 https://mkjwk.org/ and the token was created with that key on https://jwt.io 上生成的密钥(检查 'secret base64 encoded')。或者,您可以使用自己的密钥,但必须确保它足够长。
Do I need to modify my token to include the kid header somewhere?
上面的小例子没有将 kid
放入令牌中。对于任何实际应用程序,您通常会将 kid
添加到令牌 header 中。您的密钥库可能有更多密钥或旋转密钥,kid
有助于 select 正确的密钥。
我正在尝试使用 node-jose 来验证我的 JWT 的签名。我知道秘密,但无法将此秘密转换为用于验证的 JWK。
这是一个示例,说明我如何尝试使用我的秘密创建我的密钥并验证我的令牌。这导致 Error: no key found
.
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJpYWxfbnVtYmVyIjoiNWYxMGExNjMtMjk2OC00ZDZkLWIyZDgtOGQxNjQwMDNlMmQ0Iiwic2VxIjo1MTI4MTYsIm5hbWUiOiJOYW1lMSIsImlkIjo2NTQsImRlc2NyaXB0aW9uIjoiVGVzdCBEZWNvZGluZyJ9.ahLaTEhdgonxb8rfLG6NjcIg6rqbGzcHkwwFtvb9KTE"
let secret = "SuperSecretKey"
let props = {
kid: "test-key",
alg: "HS256",
use: "sig",
k: secret,
kty: "oct"
}
let key;
jose.JWK.asKey(props).then(function(result) {key = result})
jose.JWS.createVerify(key).verify(token).then(function(result){console.log(result)})
我是否需要修改我的令牌以在某处包含 kid
header?我是否根据该库的已知秘密正确生成了密钥?
您的代码存在三个问题。
由于承诺的异步性质,
key
在承诺完成时(在.then
部分)获得一个值,但这发生在下一行之后被调用。直接在行
jose.JWK.asKey(...
之后放置一个console.log(key)
,您会看到结果是“未定义”。所以其实是没有钥匙的。JWK 中的
k
值被视为 Base64Url 编码的八位字节。签署令牌时,必须使用k
的 base64url 解码值,但不能直接使用k
。秘密“SuperSecretKey”对于 node.jose 来说太短了。对于 HS256 算法,密钥长度必须为 256 位。 node.jose 与其他库相比,似乎相当严格。
要解决第一个问题,您可以嵌套调用(这很快就会变得难以阅读,或者使用如下所示的 async/await 语法:
var jose = require('node-jose')
async function tokenVerifyer()
{
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJpYWxfbnVtYmVyIjoiNWYxMGExNjMtMjk2OC00ZDZkLWIyZDgtOGQxNjQwMDNlMmQ0Iiwic2VxIjo1MTI4MTYsIm5hbWUiOiJOYW1lMSIsImlkIjo2NTQsImRlc2NyaXB0aW9uIjoiVGVzdCBEZWNvZGluZyJ9.KK9F14mwi8amhsPT7ppqp_yCYwwOGcHculKByNPlDB8"
let secret = "SuperSecretKeyThatIsLongEnough!!" // A 32 character long secret to get 256 bits.
let props = {
kid: "test-key",
alg: "HS256",
use: "sig",
k: "cynZGe3BenRNOV2AY__-hwxraC9CkBoBMUdaDHgj5bQ",
//k : jose.util.base64url.encode(secret), // alternatively use above secret
kty: "oct"
}
let key = await jose.JWK.asKey(props)
let result = await jose.JWS.createVerify(key).verify(token)
}
tokenVerifyer()
在上面的示例中,k
是在 https://mkjwk.org/ and the token was created with that key on https://jwt.io 上生成的密钥(检查 'secret base64 encoded')。或者,您可以使用自己的密钥,但必须确保它足够长。
Do I need to modify my token to include the kid header somewhere?
上面的小例子没有将 kid
放入令牌中。对于任何实际应用程序,您通常会将 kid
添加到令牌 header 中。您的密钥库可能有更多密钥或旋转密钥,kid
有助于 select 正确的密钥。