1

我正在努力在 jwcrypto 中使用相同的密钥生成与 node-jose 中等效的 JWE。目标是在 node-jose 中生成密钥并将 pubkey 导出到 jwcrypto 以加密有效负载,然后由 node-jose 使用并解密。

我的测试完全在 node-jose 工作正常:

var jose = require("node-jose")
var keyStore = jose.JWK.createKeyStore()

keyStore.generate('EC', 'P-521').then(function (result) {

    // Use exported key to encrypt something (so we see the same thing jwcrypto does)    
    jose.JWK.asKey(result.toJSON()).then(function(result) {

        jose.JWE.createEncrypt(result).update('this is a test payload').final().then(function (result) {

            jose.JWE.createDecrypt(keyStore).decrypt(result).then(function (result) {

                // Result is good
                console.log(result)
        })
    })

})

但是,当我在 python 中执行相同操作时,node-jose 会生成不同的 JWE:

    key = jwk.JWK(**json.loads(the_exported_key))

    # This key looks exactly the same as the exported key in node-jose
    print(key.export(private_key=False))

    payload = "this is a test payload"

    header = {
        'alg': 'ECDH-ES',
        'enc': 'A128CBC-HS256',
    }
    my_jwe = jwe.JWE(payload.encode('utf-8'), header)
    my_jwe.add_recipient(key)

当 node-jose 尝试解密 my_jwe 时,它​​失败并显示“错误:找不到密钥”。奇怪的是(或者不是,这是我第一次使用 JWEs ......),两个加密结果是(见下面的例子)。我想我错过了如何让 jwcrypto 像 node-jose 一样不需要“标题”值,但是当我拉取这些值时它会抱怨。

node-jose 示例(垃圾数据):

{
    ciphertext: "1e7YX6hNDJWJELhHTNXEOg",
    iv: "oQZZq2smHX8u8MMwoC6NBA",
    protected: "eyJhbGciOi".....(very long string),
    tag: "3NfEqx9f2ivL8QodG5Duaw",
}

jwcrypto(垃圾数据):

{
    ciphertext: "7ldKnkcsLZUy-SXFRv_HpkWOsb-YUUlNFv-4M5yZhCA",
    iv: "1uErMiK_RWcaPXPCPq12Uw",
    header: {
        alg: "ECDH-ES",
        enc: "A128CBC-HS256",
        epk: {
            crv: "P-521",
            kty: "EC",
            x: different from the exported key, I assume this is expected 'epk', 
            y: different from the exported key, I assume this is expected 'epk',
        },
        kid: "JCU3sWKfirVybFbpy2NPOnq-4-43JiemRZLO5dmPMVo"
    },
    tag: "51AMFyCJld5uPyMFLLl-sw",
}
4

1 回答 1

1

您使用 jwcrypto 或 node-jose 获得的结果看起来符合 RFC7516。唯一的区别是 node-jose 将您的标头设置在protected成员中(完整性保护标头),而 jwcrypto 将其设置在header成员中(每个收件人不受保护的标头)。

epk我的理解是 node-jose 会引发错误,因为它在标头(成员)中找不到公钥。它只检查不符合RFC7516 第 2 节第 4 段protected的成员而不检查其他标头(header以及成员,如果存在) 。:unprotected

让 JOSE Header 成为 JWE Protected Header、JWE Shared Unprotected Header 和相应的 JWE Per-Recipient Unprotected Header 成员的并集

从我的角度来看,当只为一个收件人创建 JWE 时,没有理由将epk成员(以及algandenc成员)设置在不受保护的标头中。这些未受保护的标头的存在将阻止您使用 JWE 紧凑序列化。所以应该改变 jwcrypto 的行为。

我不知道这两个库是如何工作的,但是有两种方法可以解决这个问题:

  • 强制 jwcrypto 使用完整性保护的标头而不是不受保护的标头(最好)。
  • 要求 node.jose 考虑其他标头(很好,但可能需要一些时间)
于 2017-10-19T06:21:01.663 回答