Skip to content

Instantly share code, notes, and snippets.

@mholt
Created June 25, 2021 20:07
Show Gist options
  • Save mholt/813db71291de8e45371fe7c4749df99c to your computer and use it in GitHub Desktop.
Save mholt/813db71291de8e45371fe7c4749df99c to your computer and use it in GitHub Desktop.
Generate key pairs and PEM-encode them using vanilla JS and browser Crypto API
//
// Convert an ArrayBuffer into a string.
// From https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
function arrayBufToString(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
}
function pemEncode(label, data) {
const base64encoded = window.btoa(data);
const base64encodedWrapped = base64encoded.replace(/(.{64})/g, "$1\n");
return `-----BEGIN ${label}-----\n${base64encodedWrapped}\n-----END ${label}-----`;
}
async function exportKeyAsString(format, key) {
const exported = await window.crypto.subtle.exportKey(format, key);
return arrayBufToString(exported);
}
async function pemEncodedPrivateKey(keyPair) {
const exported = await exportKeyAsString("pkcs8", keyPair.privateKey);
return pemEncode("PRIVATE KEY", exported);
}
async function pemEncodedPublicKey(keyPair) {
const exported = await exportKeyAsString("spki", keyPair.publicKey);
return pemEncode("PUBLIC KEY", exported);
}
window.crypto.subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-256"
},
// if using RSA, use something like this instead (https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams):
// {
// name: "RSA-PSS",
// modulusLength: 4096,
// publicExponent: new Uint8Array([1, 0, 1]),
// hash: "SHA-256",
// },
true,
["sign", "verify"]
).then(keyPair => {
pemEncodedPrivateKey(keyPair).then((privateKeyPEM) => {
console.log(privateKeyPEM);
});
pemEncodedPublicKey(keyPair).then((publicKeyPEM) => {
console.log(publicKeyPEM);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment