Max*_*pin 5 javascript cryptography webcrypto-api
私钥是使用椭圆曲线生成的。Web Crypto API 的SubtleCrypto接口中的方法似乎都无法从私钥派生公钥,如果我错了,请纠正我。我必须使用第三方库吗?
WebCrypto 是一个低级 API,只有相对较小的功能集。据我所知,没有专门的方法可以从私钥派生公钥。
但是,您可以将私有导出CryptoKey为 JWK(JSON Web 密钥),删除私有部分,然后重新导入剩余部分,从而将其变为公共CryptoKey。以下代码显示了 ECDSA 密钥的这一点:
async function getPublic(privateKey){
const jwkPrivate = await crypto.subtle.exportKey("jwk", privateKey);
delete jwkPrivate.d;
jwkPrivate.key_ops = ["verify"];
return crypto.subtle.importKey("jwk", jwkPrivate, {name: "ECDSA", namedCurve: "P-256"}, true, ["verify"]);
}
async function test(){
// Generate test key pair
const keyPair = await crypto.subtle.generateKey({name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]);
// Derive public from private key
const publicKeyFromPrivate = await getPublic(keyPair.privateKey)
// Compare CryptoKeys
console.log(keyPair.publicKey);
console.log(publicKeyFromPrivate)
// Compare keys (in JWK format)
const jwkPublic = await crypto.subtle.exportKey("jwk", keyPair.publicKey);
const jwkPublicFromPrivate = await crypto.subtle.exportKey("jwk", publicKeyFromPrivate);
console.log(jwkPublic);
console.log(jwkPublicFromPrivate);
}
(async () => {
await test()
})();Run Code Online (Sandbox Code Playgroud)
正如您所看到的,原始和重建的公钥是相同的。
然而,应该提到的是,该解决方案有一个缺点:私钥必须是可导出的。
这篇文章展示了 RSA 的相同方法。