Supra_App/src/lib/core/utils/crypto.ts

69 lines
2.1 KiB
TypeScript
Raw Normal View History

export class WebCryptoHelper {
static async generateKeyPair() {
const keyPair = await window.crypto.subtle.generateKey(
{
name: 'ECDH',
namedCurve: 'P-256'
},
true,
['deriveKey', 'deriveBits']
);
const exportedPublic = await window.crypto.subtle.exportKey('raw', keyPair.publicKey);
const publicKeyBase64 = btoa(String.fromCharCode(...new Uint8Array(exportedPublic)));
return { privateKey: keyPair.privateKey, publicKeyBase64 };
}
static async deriveSharedKey(clientPrivateKey: any, serverPublicKeyBase64: any) {
const binarySign = atob(serverPublicKeyBase64);
const bytes = new Uint8Array(binarySign.length);
for (let i = 0; i < binarySign.length; i++) {
bytes[i] = binarySign.charCodeAt(i);
}
const importedServerPublic = await window.crypto.subtle.importKey(
'raw',
bytes,
{ name: 'ECDH', namedCurve: 'P-256' },
true,
[]
);
return await window.crypto.subtle.deriveKey(
{ name: 'ECDH', public: importedServerPublic },
clientPrivateKey,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
}
static async decryptMessage(aesKey: any, ciphertextBase64: any, ivBase64: any) {
const rawCipher = Uint8Array.from(atob(ciphertextBase64), (c) => c.charCodeAt(0));
const rawIv = Uint8Array.from(atob(ivBase64), (c) => c.charCodeAt(0));
const decryptedBuffer = await window.crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: rawIv },
aesKey,
rawCipher
);
return new TextDecoder().decode(decryptedBuffer);
}
// Encrypt outgoing messages before sending them to your Axum backend
static async encryptMessage(aesKey: any, plainText: any) {
const iv = window.crypto.getRandomValues(new Uint8Array(12)); // 12-byte nonce
const encodedText = new TextEncoder().encode(plainText);
const ciphertextBuffer = await window.crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
aesKey,
encodedText
);
const ciphertextBase64 = btoa(String.fromCharCode(...new Uint8Array(ciphertextBuffer)));
const ivBase64 = btoa(String.fromCharCode(...iv));
return { ciphertext: ciphertextBase64, iv: ivBase64 };
}
}