从 PEM 导入 JWK 时如何覆盖自动计算的孩子

Posted

技术标签:

【中文标题】从 PEM 导入 JWK 时如何覆盖自动计算的孩子【英文标题】:How can I overwrite the automatically calculated kid when importing a JWK from PEM 【发布时间】:2022-01-24 06:32:20 【问题描述】:

我正在尝试使用 node-jose 库的 createEncrypt 方法创建 JWE 令牌。问题是,我想将kid 设置为某个值。但是当使用jose.JWK.asKey 方法导入密钥时,它会自动计算kid 并且不会让我更改/设置它。下面是示例代码:

const  JWK, JWE  = require('node-jose');
encrypt = async (raw, format = 'compact', contentAlg = "A128CBC-HS256", alg = "RSA-OAEP-256") => 
    let _publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxO+O52a1eAkbYatqpPAk
vhTz5VAdNloWhbmAmwPQl9202VKxU+yOCbwZSU8NqwVubHMgnxdycgJw+zGslXgz
zHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxgle
bvDyhfoHMGVSYiP89UQPTR+uu6irFRkdu2zFDPOx2/4XdtyAbJlWdj4Fes0v3CcA
/jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW+mXn+m
IfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z+m7AeIHtC+ol0/eBPYPwk
PQIDAQAB
-----END PUBLIC KEY-----`
    let publicKey = await JWK.asKey(_publicKey, "pem");
    publicKey.kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
    console.log(publicKey)
    const buffer = Buffer.from(JSON.stringify(raw))
    const encrypted = await JWE.createEncrypt( format: format, contentAlg: contentAlg, fields:  alg: alg, iat: (new Date().getTime()), exp: 30000 , publicKey)
        .update(buffer).final();
    return encrypted;

let raw = 
    "mobileNumber": "1234567890",
    "customerId": "000000000",
    "sessionId": "3a600342-a7a3-4c66-bbd3-f67de5d7096f",
;
encrypt(raw).then((data)=> console.log(data))

这是生成的加密 JWE Token:

eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJpYXQiOjE2NDAyNDU0NzY5ODEsImV4cCI6MzAwMDAsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiI1bUxtdmVHdng0RHVucGlfTnBhajhxZlByRHNDYW9NV29JeWRoM003SzA4In0.SUpO7X0XXbkqQtNGVvLMNo6oGi1GrTzAR1FtXlL8ngg9Uvd91nkLiRqgcmjKBBEE1M330WV_HrUYNs2NVRcXTDcr41fSwvHSu7veK_YDj-m73LoMKlmojeB6GIRUIXIw7oaqgFSOSb_Xgq_zwG9WGa07h2OgOzeFxKNJCvt1J2i_v2Tt61yyet0hdMinT78whDGgf_JW4LUSaXY9wsqsuQSDkKWFLvxHqNmq7nGPLpgEJjm1GPF0slPvdWsARsMEttbPK9VpoMUvMcqy5bWVWSmj2MEGTVw6ua-uFw9fEgyn095wl-s8lEfZFkFaiFN7ps5VwqVV2tihpnYrCVIYAA.jxR4Gw_Gcy9Sexw-wMBKtQ.TzugQZCFgQiolIBc2FAEQ0ZbvNdPFzE2z0m9cFxWQtADEijOCzQjZreVvnsVjHFXdP_w-YcnCbmKXkwalWnFMo7wkjuuJ0fAsTfTOEiBjuIPvMa0k04C97Rc4ZYszzzL7xxwW0RnqoNxiQMkea3H0A.qAqgcg_DLV1vHzb0EIq-9A

如果您在jwt.io 上进行检查,您可以看到kid 已经计算和设置。如何在此处设置/更改kid

【问题讨论】:

【参考方案1】:

如果在导入过程中不知道孩子,则会自动计算:

当导入或生成未定义“孩子”的密钥时,会计算“SHA-256”指纹并将其用作“孩子”。

(见https://github.com/cisco/node-jose#obtaining-a-keys-thumbprint)

但是在对JWK.asKey 的调用中,您可以传递一个附加参数extras,它为现有字段设置值或包含JWK 的附加字段。 对于您的用例,您可以将 kid 设置为 JSON 对象

let kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
let publicKey = await JWK.asKey(_publicKey, "pem", "kid":kid);
console.log(publicKey.toJSON())

输出:


  kty: 'RSA',
  kid: '932ea6bb-2623-4dc3-96b1-c4be61e97569',
  n: 'xO-O52a1eAkbYatqpPAkvhTz5VAdNloWhbmAmwPQl9202VKxU-yOCbwZSU8NqwVubHMgnxdycgJw-zGslXgzzHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxglebvDyhfoHMGVSYiP89UQPTR-uu6irFRkdu2zFDPOx2_4XdtyAbJlWdj4Fes0v3CcA_jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW-mXn-mIfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z-m7AeIHtC-ol0_eBPYPwkPQ',
  e: 'AQAB'

【讨论】:

这对JWE的输出有影响吗?我的意思是这会影响加密吗? 生成的 JWE 将在您在此处设置的标头中包含 child 值,这就是您想要的。除此之外,没有其他效果。只需将上面的代码sn-p放到你的代码中,看看结果。

以上是关于从 PEM 导入 JWK 时如何覆盖自动计算的孩子的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Delphi 中将 JSON Web Key 转换为 PEM 格式?

核心数据:检测孩子何时被删除

从 JWT 令牌获取 UserInfo 信息并在 Spring Boot OAuth2 自动配置上仅使用 JWK 验证

如何从 RSA 密钥对创建 JWK?

如何从 JWK 密钥集中选择有效密钥进行苹果登录令牌验证?

错误:导入“pem”密钥时没有密钥导入程序