beeta/frontend/src/lib/pgp.js

99 lines
3 KiB
JavaScript
Raw Normal View History

2025-08-03 21:53:15 -04:00
// Client-side PGP utilities - wraps openpgp for browser-only usage
export async function generateKeyPair(username, passphrase = '') {
if (typeof window === 'undefined') {
throw new Error('PGP operations can only be performed in the browser');
}
const { generateKey, readKey } = await import('openpgp');
const { privateKey, publicKey } = await generateKey({
type: 'rsa',
rsaBits: 2048,
userIDs: [{ name: username }],
passphrase
});
const key = await readKey({ armoredKey: publicKey });
const fingerprint = key.getFingerprint();
return {
privateKey,
publicKey,
fingerprint
};
}
export async function getFingerprint(publicKey) {
if (typeof window === 'undefined') return null;
try {
const { readKey } = await import('openpgp');
const key = await readKey({ armoredKey: publicKey });
return key.getFingerprint();
} catch (error) {
console.error('Error getting fingerprint:', error);
return null;
}
}
export async function signMessage(message, privateKeyArmored, passphrase = '') {
if (typeof window === 'undefined') {
throw new Error('PGP operations can only be performed in the browser');
}
const { decryptKey, readPrivateKey, createMessage, sign } = await import('openpgp');
const privateKey = await decryptKey({
privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }),
passphrase
});
const unsignedMessage = await createMessage({ text: message });
const signature = await sign({
message: unsignedMessage,
signingKeys: privateKey,
detached: true
});
return signature;
}
export async function verifySignature(message, signature, publicKeyArmored) {
if (typeof window === 'undefined') return false;
try {
const { readKey, readSignature, createMessage, verify } = await import('openpgp');
const publicKey = await readKey({ armoredKey: publicKeyArmored });
const signatureObj = await readSignature({ armoredSignature: signature });
const messageObj = await createMessage({ text: message });
const verificationResult = await verify({
message: messageObj,
signature: signatureObj,
verificationKeys: publicKey
});
const { verified } = verificationResult.signatures[0];
return await verified;
} catch (error) {
console.error('Signature verification error:', error);
return false;
}
}
export function storePrivateKey(privateKey) {
if (typeof window === 'undefined') return;
localStorage.setItem('pgp_private_key', privateKey);
}
export function getStoredPrivateKey() {
if (typeof window === 'undefined') return null;
return localStorage.getItem('pgp_private_key');
}
export function removeStoredPrivateKey() {
if (typeof window === 'undefined') return;
localStorage.removeItem('pgp_private_key');
}