Deriving an RSA Public Key from a Private Key Using the Web Crypto API
While tools such as OpenSSL or Node.js provide methods to derive the public key from the private key:
- openssl:
openssl rsa -pubout -in private.pem -out public.pem
- node.js:
crypto.createPublicKey(privateKey)
https://nodejs.org/api/crypto.html#cryptocreatepublickeykey
The Web Crypto API does not include a direct method to derive an RSA public key from a private key.
However, you can achieve this by exporting the private key in JSON Web Key (JWK) format, extracting the modulus (n
) and public exponent (e
), and re-importing them as a public key.
Below is a concise example:
async function publicKeyFromPrivateKey(privateKeyPem) {
const base64 = pemToBase64(privateKeyPem); // remove PEM headers, decode Base64
const keyData = base64ToUint8Array(base64); // convert to Uint8Array
const rsaParams = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
const privateKey = await crypto.subtle.importKey("pkcs8", keyData, rsaParams, true, ["sign"]);
const privateKeyJwk = await crypto.subtle.exportKey("jwk", privateKey);
const { n, e } = privateKeyJwk;
const publicKeyJwk = { kty: "RSA", e, n };
return crypto.subtle.importKey("jwk", publicKeyJwk, rsaParams, true, ["verify"]);
}
- Convert the PEM to Base64 and then to a
Uint8Array
. - Import the private key using
importKey
. - Export the key in JWK format, revealing the public components.
- Create a new JWK with
n
ande
, then import it as a public key.
You can find the full example on GitHub: https://gist.github.com/PutziSan/99a1aaede16c3f223fd59ae6d47a0d5e
Interactive Example
Below is an interactive example to derive the public key from a private key using the Web Crypto API directly in the browser (no server-side processing required, your private key stays private):
Generated Public Key in PEM format: