Generate Public key from Private Key using WebCrypto API
Asked Answered
M

1

7

I'm using Web Crypto API and am generating RSA Keypair using generateKey function. Because of some bugs in my code, I have deleted public key for some users. I'm wondering if there is any way to generate public key out of private key? I know that it's easily doable for ssh keys. Here is my sample code for generating RSA key pair:

const generateRSAKeys = (): Promise<CryptoKeyPair> => {
    return crypto.subtle.generateKey(
    {
        name: 'RSA-OAEP',
        modulusLength: 2048
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: { name: 'SHA-512' },
    },
    true,
    ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'],
);
Marlinmarline answered 28/6, 2019 at 13:35 Comment(2)
The public key consists essentially of the modulus and public exponent, both of which are also part of the private key. So yes, this is certainly possible (trivial, even). How to do it exactly depends on the format that the private key is stored in, and the format you need the public key to be in.Punctuation
Nitpick: the public exponent is not part of the private key, but must formats include it for convenience (including the one in PKCS#1, so yeah, almost universal).Flunk
S
7

You can do it by exporting private key and importing exported data like public data

const keys = await crypto.subtle.generateKey(
  {
    name: 'RSA-OAEP',
    modulusLength: 2048,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: { name: 'SHA-512' },
  },
  true,
  ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'],
);

// export private key to JWK
const jwk = await crypto.subtle.exportKey("jwk", keys.privateKey);

// remove private data from JWK
delete jwk.d;
delete jwk.dp;
delete jwk.dq;
delete jwk.q;
delete jwk.qi;
jwk.key_ops = ["encrypt", "wrapKey"];

// import public key
const publicKey = await crypto.subtle.importKey("jwk", jwk, { name: "RSA-OAEP", 
hash: "SHA-512" }, true, ["encrypt", "wrapKey"]);

console.log(publicKey)

enter image description here

Sheeting answered 20/8, 2019 at 10:11 Comment(5)
How can I adjust this for ECDSA?Emmert
What if the private key is not extractableAllonge
It's impossible to get public key data from an unextractable private keySheeting
For ECDSA s. e.g. here.Byssus
Side note: described tactic work if you get a private key for import, e. g. as PKCS8. First import arriving private key as extractable, export it as JWK, crop private fields, and than imprting resulting JWK as extractable public key with relevant usages, and import the incoming private key as usual. Then you can construct a CryptoKeyPair where final private key can even be marked as non-extractable, if you save these CryptoKeyPair instances in indexedDB for example.Norine

© 2022 - 2024 — McMap. All rights reserved.