Skip to content

Instantly share code, notes, and snippets.

@to
Created February 13, 2026 20:37
Show Gist options
  • Select an option

  • Save to/a52f953db458c452ee7c0fa98e8519ec to your computer and use it in GitHub Desktop.

Select an option

Save to/a52f953db458c452ee7c0fa98e8519ec to your computer and use it in GitHub Desktop.
// generate_key.js
// No dependencies! Using only Web Crypto API and Deno built-ins.
async function main() {
console.log('Generating RSA Key Pair...');
// 1. Generate RSA Key Pair
const keyPair = await crypto.subtle.generateKey(
{
name: 'RSASSA-PKCS1-v1_5',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: 'SHA-256',
},
true,
['sign', 'verify'],
);
// 2. Export Private Key (PKCS#8) -> Save as key.pem
const privateKeyDer = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
const privateKeyBytes = new Uint8Array(privateKeyDer);
let privateKeyString = '';
for (let i = 0; i < privateKeyBytes.length; i++)
privateKeyString += String.fromCharCode(privateKeyBytes[i]);
const privateKeyBase64 = btoa(privateKeyString);
const pemContent = `-----BEGIN PRIVATE KEY-----\n${privateKeyBase64.match(/.{1,64}/g).join('\n')}\n-----END PRIVATE KEY-----\n`;
await Deno.writeTextFile('key.pem', pemContent);
console.log('✅ key.pem generated.');
// 3. Export Public Key (SubjectPublicKeyInfo)
const publicKeyDer = await crypto.subtle.exportKey('spki', keyPair.publicKey);
const publicKeyBytes = new Uint8Array(publicKeyDer);
let publicKeyString = '';
for (let i = 0; i < publicKeyBytes.length; i++)
publicKeyString += String.fromCharCode(publicKeyBytes[i]);
const publicKeyBase64 = btoa(publicKeyString);
// This Base64 string is what we need for manifest.json "key" field!
await Deno.writeTextFile('manifest_key.txt', publicKeyBase64);
console.log('✅ manifest_key.txt generated.');
// 4. Calculate Extension ID
// SHA-256 of SubjectPublicKeyInfo
const hashBuffer = await crypto.subtle.digest('SHA-256', publicKeyDer);
const hashArray = new Uint8Array(hashBuffer);
// Take first 16 bytes (128 bits)
const idBytes = hashArray.subarray(0, 16);
// Convert to 'a'-'p' mapped string
let id = '';
for (const byte of idBytes) {
// High nibble
id += String.fromCharCode(((byte >> 4) & 0x0F) + 97); // 0->a, 15->p
// Low nibble
id += String.fromCharCode((byte & 0x0F) + 97); // 0->a, 15->p
}
await Deno.writeTextFile('extension_id.txt', id);
console.log(`✅ Extension ID: ${id}`);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment