1

我正在尝试使用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某处包含标题?我是否从该库的已知秘密中正确生成了密钥?

4

1 回答 1

1

您的代码存在三个问题。

  1. 由于 Promise 的异步特性,key当 Promise 完成时(在.then部分中)获得一个值,但这发生在下一行被调用之后。

    将 aconsole.log(key)直接放在该行之后jose.JWK.asKey(...,您会看到结果是“未定义”。所以实际上没有钥匙。

  2. JWK 中的k值被视为 Base64Url 编码的八位字节。当您签署令牌时,您必须使用 base64url 的解码值k,但不能k直接使用。

  3. 秘密“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/上生成的密钥,并且令牌是在https://jwt.io上使用该密钥创建的(检查“秘密 base64 编码”)。或者,您可以使用自己的秘密,但必须确保它足够长。

我是否需要修改我的令牌以在某处包含孩子标头?

上面的小例子可以在没有放入kid令牌的情况下工作。对于任何真正的应用程序,您通常会将其添加kid到令牌标头中。您的密钥库可能有更多密钥或旋转密钥,并且kid有助于选择正确的密钥。

于 2021-12-28T17:20:06.733 回答