mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
refactor: update crypto to generate iv on demand
This commit is contained in:
@@ -1,7 +1,3 @@
|
|||||||
/**
|
|
||||||
* 0 knowledge cryptography. No Server involved in encryption/decryption
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface EncryptedLetter {
|
export interface EncryptedLetter {
|
||||||
encrypted_content: string;
|
encrypted_content: string;
|
||||||
encrypted_dek: string;
|
encrypted_dek: string;
|
||||||
@@ -30,9 +26,6 @@ export class CryptoUtils {
|
|||||||
private static readonly PBKDF2_ITERATIONS = 100_000;
|
private static readonly PBKDF2_ITERATIONS = 100_000;
|
||||||
private static readonly AES_GCM = { name: "AES-GCM", length: 256 };
|
private static readonly AES_GCM = { name: "AES-GCM", length: 256 };
|
||||||
|
|
||||||
private readonly contentIV = crypto.getRandomValues(new Uint8Array(12));
|
|
||||||
private readonly dekIV = crypto.getRandomValues(new Uint8Array(12));
|
|
||||||
|
|
||||||
// Generates a fresh Data Encryption Key (DEK)
|
// Generates a fresh Data Encryption Key (DEK)
|
||||||
async initialize() {
|
async initialize() {
|
||||||
this.dek = await crypto.subtle.generateKey(CryptoUtils.AES_GCM, true, [
|
this.dek = await crypto.subtle.generateKey(CryptoUtils.AES_GCM, true, [
|
||||||
@@ -69,7 +62,6 @@ export class CryptoUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives a Key Bundle (MasterKey + AuthHash) from a password + email.
|
* Derives a Key Bundle (MasterKey + AuthHash) from a password + email.
|
||||||
* Absolute zero knowledge!!
|
|
||||||
*/
|
*/
|
||||||
public static async deriveKeyBundle(
|
public static async deriveKeyBundle(
|
||||||
password: string,
|
password: string,
|
||||||
@@ -118,16 +110,16 @@ export class CryptoUtils {
|
|||||||
return { masterKey, authHash };
|
return { masterKey, authHash };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal helper to encrypt data and wrap the key
|
|
||||||
private async sealEnvelope(
|
private async sealEnvelope(
|
||||||
input: Uint8Array,
|
input: Uint8Array,
|
||||||
masterKey: CryptoKey,
|
masterKey: CryptoKey,
|
||||||
): Promise<SealedEnvelope> {
|
): Promise<SealedEnvelope> {
|
||||||
const plainBytes = new Uint8Array(input);
|
const plainBytes = new Uint8Array(input);
|
||||||
|
const contentIV = crypto.getRandomValues(new Uint8Array(12));
|
||||||
|
const dekIV = crypto.getRandomValues(new Uint8Array(12));
|
||||||
|
|
||||||
// encrypt the content with the DEK
|
|
||||||
const ciphertext = await crypto.subtle.encrypt(
|
const ciphertext = await crypto.subtle.encrypt(
|
||||||
{ name: "AES-GCM", iv: this.contentIV },
|
{ name: "AES-GCM", iv: contentIV },
|
||||||
this.dek,
|
this.dek,
|
||||||
plainBytes,
|
plainBytes,
|
||||||
);
|
);
|
||||||
@@ -135,20 +127,20 @@ export class CryptoUtils {
|
|||||||
// wrap the DEK with the Master Key (for self/owner access)
|
// wrap the DEK with the Master Key (for self/owner access)
|
||||||
const wrappedDek = await crypto.subtle.wrapKey("raw", this.dek, masterKey, {
|
const wrappedDek = await crypto.subtle.wrapKey("raw", this.dek, masterKey, {
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
iv: this.dekIV,
|
iv: dekIV,
|
||||||
});
|
});
|
||||||
|
|
||||||
// export raw DEK for the share URL (recipient access, no master key needed)
|
// export raw DEK for the share URL (recipient access, no master key needed)
|
||||||
const rawDek = await crypto.subtle.exportKey("raw", this.dek);
|
const rawDek = await crypto.subtle.exportKey("raw", this.dek);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
encryptedContent: this.packWithIv(this.contentIV, ciphertext),
|
encryptedContent: this.packWithIv(contentIV, ciphertext),
|
||||||
encrypted_dek: this.packWithIv(this.dekIV, wrappedDek),
|
encrypted_dek: this.packWithIv(dekIV, wrappedDek),
|
||||||
sharingKey: this.toBase64(new Uint8Array(rawDek)),
|
sharingKey: this.toBase64(new Uint8Array(rawDek)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal helper to unwrap the key and decrypt data
|
// Unwrap the DEK with the master key to get the key back. Decrypt the content with the DEK.
|
||||||
private async openEnvelope(
|
private async openEnvelope(
|
||||||
encryptedContent: string,
|
encryptedContent: string,
|
||||||
encrypted_dek: string,
|
encrypted_dek: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user