import * as openpgp from 'openpgp' /** * Generate an OpenPGP RSA key pair. * * @param name - User name for the key * @param email - User email for the key * @returns ASCII-armored private and public keys */ export const generatePgpKeyPair = async ( name: string, email: string, ): Promise<{ privateKey: string; publicKey: string }> => { const { privateKey, publicKey } = await openpgp.generateKey({ type: 'rsa', rsaBits: 2048, userIDs: [{ name, email }], format: 'armored', }) return { privateKey, publicKey } } /** * Create a detached OpenPGP signature for the given data. * * @param data - Raw data to sign (Buffer or Uint8Array) * @param armoredPrivateKey - ASCII-armored private key * @returns ASCII-armored detached signature (signature.asc content) */ export const pgpSignDetached = async (data: Uint8Array, armoredPrivateKey: string): Promise => { const privateKey = await openpgp.readPrivateKey({ armoredKey: armoredPrivateKey }) const message = await openpgp.createMessage({ binary: data }) const signature = await openpgp.sign({ message, signingKeys: privateKey, detached: true, format: 'armored', }) return signature as string } /** * Verify a detached OpenPGP signature. * * @param data - Original data (Buffer or Uint8Array) * @param armoredSignature - ASCII-armored detached signature * @param armoredPublicKey - ASCII-armored public key * @returns true if signature is valid */ export const pgpVerifyDetached = async ( data: Uint8Array, armoredSignature: string, armoredPublicKey: string, ): Promise => { const publicKey = await openpgp.readKey({ armoredKey: armoredPublicKey }) const signature = await openpgp.readSignature({ armoredSignature }) const message = await openpgp.createMessage({ binary: data }) const verificationResult = await openpgp.verify({ message, signature, verificationKeys: publicKey, }) const { verified } = verificationResult.signatures[0]! try { await verified return true } catch { return false } }