Files
fullstack-starter/packages/crypto/src/pgp.ts

80 lines
2.2 KiB
TypeScript

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 validatePgpPrivateKey = async (armoredKey: string): Promise<void> => {
await openpgp.readPrivateKey({ armoredKey })
}
export const pgpSignDetached = async (data: Uint8Array, armoredPrivateKey: string): Promise<string> => {
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<boolean> => {
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
}
}