Web加密API - ECDH - 可以仅使用私钥组件导入私钥,而不使用公钥组件?

时间:2018-01-23 16:20:58

标签: webcryptoapi ecdhe ecdh

给定P-256椭圆曲线Diffie-Hellman私钥(它只是一个随机的256位整数):是否可以使用window.crypto.subtle.importKey将此私钥导入CryptoKey对象( )Web Crypto API的方法 - 没有公钥组件?

我知道如果公钥组件(源自私钥组件)也可用,则可以导入私钥。例如,以下代码成功运行:

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
    {
    "crv":"P-256",
    "d":"eM8u2176zFk9bwDP_jbJqnm-TlSo6GX702D9I_1AqBU",
    "ext":true,
    "key_ops":["deriveKey","deriveBits"],
    "kty":"EC",
    "x":"5Uw_SuaGZTFAuQuDArnLEmmyp4TpHx3AlBxL4EUEzbQ",
    "y":"RO5t581VBuAKTQZVPSB__ebV6y9GCzrl8lBV2-p9BlM"
    },
    {   //these are the algorithm options
    name: "ECDH",
    namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    true, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
)
.then(function(key) {
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

但是,如果只有私钥组件可用,没有公钥组件,如下面的代码所示,Web Crypto API会抛出一个DOMException,并显示消息'提供给操作的数据不符合要求'。

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
    {
    "crv":"P-256",
    "d":"eM8u2176zFk9bwDP_jbJqnm-TlSo6GX702D9I_1AqBU",
    "ext":true,
    "key_ops":["deriveKey","deriveBits"],
    "kty":"EC"
    },
    {   //these are the algorithm options
    name: "ECDH",
    namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    true, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
)
.then(function(key) {
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

我也尝试过使用pkcs8格式代替JWK,但也没有运气。

Web Crypto API的文档显示可以以JWK格式导入ECDH私钥 - 因此,似乎应该可以在没有公钥组件的情况下这样做(Web Crypto API应该如果需要,可以在内部从私钥组件计算公钥组件,就像使用.generateKey()方法一样。但是,importKey()方法似乎仅在包含公钥组件时才有效。

我在这里遗漏了什么吗?如果没有,有没有人知道解决方案或解决方法,除了在导入之前单独计算公钥组件,并在importKey()方法中包含私钥组件(这看起来过于繁琐和不必要)?

2 个答案:

答案 0 :(得分:0)

您始终可以通过标量将私钥与您选择的曲线的基点(或生成点)相乘来从私钥派生公共点。如何完成此操作取决于您的运行时环境。

答案 1 :(得分:0)

如果您具有pkcs8格式,则可以使用以下格式:

crypto.subtle.importKey("pkcs8", [privateKeyBuffer],{name:"ECDH",namedCurve:"P-256"} , true, ["deriveKey"]);