Encripting a file on the Client side.
Is the following method a valid and secure way to encrypt files?
Does it work with large files (is the entire file stored in Memory during the process)?
const encryptFile = async (
file: Blob
): Promise<{ key: CryptoKey; buffer: Buffer }> => {
const fileBuffer = await file.arrayBuffer();
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 128 },
true, // extractable
["encrypt", "decrypt"]
);
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv: new Uint8Array(12) /* don't reuse key! */ },
key,
fileBuffer
);
const buf = Buffer.from(encrypted);
return { key, buffer: buf };
};
Are there any Better ways?
Why I need it
I want to build an E2E encryption into my file-sharing site. After encrypting the file with the posted method, I upload it to the server as a binary file.
CodePudding user response:
Is it secure? Well, against what?
The code doesn't reuse the key - it claims, and GCM is considered secure.
Not sure why you would be using 128 bits though, 256 bits is generally not much slower or just as fast.
Will the message and ciphertext be in memory?
Blob.prototype.arrayBuffer()
Returns a promise that resolves with an
ArrayBuffer
containing the entire contents of the Blob as binary data.
So yes. I'd at least zero out that data right after encryption. Furthermore, it very much depends what you now will do with the randomly generated key.
I'd warn against using GCM for too large a file, it is certainly limited to 64 GiB - 32 bytes internally, after that the internal counter will start to repeat. Still sounds large, but since I'm typing this on a computer with 32 GiB of RAM...