I'm trying to build a method for encrypting a file client side and upload it. The goal is to store the file encrypted on the server and only the end-user should be able to decrypt the file. This question has sort of been asked before, but I think I made some more progress.
My plan is to use the new Javascript File API to manipulate the file and upload it. Encryption could be done with the Stanford Javascript Crypto Library. The file should be read in chunks so it isn't completely read into memory. Every chunk is then encrypted by the crypt library. I can't figure out how to implement this. As a start I have this:
var fd = new FormData();
var file = document.getElementById('file').files[0];
fd.append("file", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload/");
xhr.send(fd);
Which is just a regular javascript upload. I'm trying to build a Crypt object that mimics the behavior of a File object and pass this to FormData. For every data chunk read by formdata the object should read a chunk from the file and encrypt this. I just can't figure out how FormData is processing a File object and if it possible to replicate this behavior. I'm not sure if it is the right way to do it, anybody has a suggestion?
UPDATE: Ok I'm much further now. I'm using file.slice to read the file in chunks. Then every chunk is encrypted and transformed back into a blob using a the BlobBuilder. This blob is then put into a FormData object and submitted to the server. The server will concatenate these blobs. Encrypting and decrypting one chunk with the browser is working. Now I'm working on download and decrypting multiple chunks.
There are still some problems to solve:
- The name of the file is lost, it is not yet possible to set a FileName for a file object.
- The encryption is still blocking (no ui update), but I think I can solve this with webworkers.
- I can't predict the chunk size while downloading. The unencrypted chunk size is known, but for encrypted data this seems to differ. This encrypted data is stored in JSON form, I prefer not to do a string search for }. And I prefer not to store this server side.
- Although I'm reading the file chunked, Firefox seemt to have a memory leak or read the complete file into memory. This becomes a problem for multi gigabyte files.