Skip to content

Instantly share code, notes, and snippets.

@PutziSan
Last active December 26, 2024 12:42
Show Gist options
  • Save PutziSan/99a1aaede16c3f223fd59ae6d47a0d5e to your computer and use it in GitHub Desktop.
Save PutziSan/99a1aaede16c3f223fd59ae6d47a0d5e to your computer and use it in GitHub Desktop.
Get RSA Public Key from a Private Key Using the Web Crypto API
function base64ToUint8Array(base64) {
return new Uint8Array(
atob(base64)
.split("")
.map((c) => c.charCodeAt(0)),
);
}
function pemToBase64(pem) {
return pem
.replace(/-----BEGIN (.*)-----/, "")
.replace(/-----END (.*)-----/, "")
.replace(/\s/g, ""); // Remove all whitespace characters
}
async function publicKeyFromPrivateKey(privateKeyPem) {
const base64 = pemToBase64(privateKeyPem);
const keyData = base64ToUint8Array(base64);
const privateKey = await crypto.subtle.importKey(
"pkcs8",
keyData,
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
true, // extractable
["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,
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
true,
["verify"],
);
}
function arrayBufferToBase64(arrayBuffer) {
return btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
}
function arrayBufferToPublicKeyPem(buffer) {
const base64 = arrayBufferToBase64(buffer);
const pemFormattedBlocks = base64.match(/.{1,64}/g)?.join("\n") || ""; // Format the Base64 string into PEM blocks
return `-----BEGIN PUBLIC KEY-----\n${pemFormattedBlocks}\n-----END PUBLIC KEY-----`;
}
const privateKeyPemExample = `-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDN5RBYr+zPc3o2
tiajqUILJktKcEek0DhAC48yB0HYYEf/bTb1dXrvzKUJCdK+ndeazZAUHmL+J0mJ
BYc5dv40vkds3ScYipAAxtS5PjQjQJjxHit04oM2iTkRUFUZHl6me28oInCN+iK0
pMkPTucf8H+Eax6p90gFa5e8yjosVWYpdW/FAsW9Vs5gNoczSLFB/mLTQR/3kQFC
zlKXMflJZEnVxN7xsmAy4nPeNrf1SzcJ7ZPyzeTzk/mnfKJcGQ9reUfUAD+Npukm
U4RSq/V+hjuUN61ldVGPfxKvepvEhrLMYq72UYfOjRO7xjiC1kltHWCylpeOyJIS
kpOfG61lAgMBAAECggEBAMpcRECmR71s5cU4KanZBQwoSv+ScxfNfjuUIN0uvMyJ
dLnbAZUmLfnZzKqhePvX7rw7JUxgwTLCMkf1ov4bsaTtDw40HeTE6tuYkCKwvFWZ
e7gfyt5KcmP7YpdduQXDD4vY7Vso3i7slYeuHd5p0kdV/D6NecnbPHH3WV838wz1
7lGFY7As0Kqm0UTooUzZsOmgJQEU/VieKnSndFa1u0NxlxrvnptJTXjNNgs+S03f
Bj/tYB4GznJj8bV5M0PlcsN1riT8qvwwYxI0KTzdFEEX79fzSQcmgyPooPNcnHRO
Jbtz5K7jmdmYG+YlO59OOfG0thtFEJz/otQQmlvEQwECgYEA8hOuNvfwJa3TThaK
NxYXld2Trf/7eO0UaDERMqJ4AkEW/IGuJLKU6USqqH1/spFR7N7iC2/y+mwtQBCV
5skMmc/X20MHrFlIyfC0ra13Yu8JUjw42dD0KkCPhZqvd82Fu3OLe7pBGQ4qYbgI
VzRDO6sKW0wXe47yA38RHjApBBECgYEA2bykJZcpa0xjSvPFP2JBWO9Peqafn6Rk
1ajzIA8DTxW7aj6FTjXc7taVV0JttPKdPeY5v2BYeVUz7nmvjIt2cENA82I8kcU2
tu0pd+AUwcCD+3Oc9ORUFymf9sjoZJXPoK66rd++z6Sawq6rOaHWyeg76R5XIJHX
Wj4GuBtQ2BUCgYEA00z0c4yl9O2ulOm9yWmiOrFHN8lKQvqGJpA118HTCPyxyMSV
MfkjXB4Q7LNm5IJORXkjTCJyr73/HX2cqu7w7c1rODthFkJ087gErdjNbfECbOKe
KRpoFf12iYNFCEjAI6gup1gjfHBN9DAEL8IxsYKRrrFTiglzHDQsx/H3y1ECgYEA
g1De2oDpDPo75AdSzaBPcviZQYpeOKSn36gOQSZsw3SC3Feqg/m+LhkiZkb87SVp
KdzAtSfBFCQLtuaStjuiCaC1+lMj3nJHRlmQKejt+9BEiRE39wYBpRqIjAitB4TG
fM0EbzrC1G4cnA9F2vM9G/ZAs56Fw3HRpG5GFSD8R+UCgYEAvuCXQYqHfI5vPSve
bYVYSGawad7RJXxVywV/T3FpGwByC7V3uCZQ9A1sO6ccEVmny9Go1oywJUtimmyn
x9q/peddCvS5GflqLcdMMhVZFqeGw5stpPaOoU2JHLCewp846vtfxWY8C5jNwMLv
wbUTu84yohq4QhPxYZVkdhBJVzs=
-----END PRIVATE KEY-----`;
const publicKey = await publicKeyFromPrivateKey(privateKeyPemExample);
const publicKeySpki = await crypto.subtle.exportKey("spki", publicKey);
const publicKeyPem = arrayBufferToPublicKeyPem(publicKeySpki);
console.log(publicKeyPem);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment