3

Im trying to run in-browser encryption application which uses jQuery 1.10.2 and CryptoJS 3.2.1 the problem that I face starts at around 2mb files. File can be encrypted just fine, but when a data URI is created for the file it crashes the browser.

I would like a way around this to make it possible to encrypt files up-to 50mb's without browser crashing.

Here is the current snippt responsible for file saving via FileReader API

var reader = new FileReader();

        if(body.hasClass('encrypt')){

            // Encrypt the file!

            reader.onload = function(e){

                // Use the CryptoJS library and the AES cypher to encrypt the 
                // contents of the file, held in e.target.result, with the password

                var encrypted = CryptoJS.AES.encrypt(e.target.result, password);

                // The download attribute will cause the contents of the href
                // attribute to be downloaded when clicked. The download attribute
                // also holds the name of the file that is offered for download.

                a.attr('href', 'data:application/octet-stream,' + encrypted);
                a.attr('download', file.name + '.encrypted');

                step(4);
            };

            // This will encode the contents of the file into a data-uri.
            // It will trigger the onload handler above, with the result

            reader.readAsDataURL(file);
        }
        else {

            // Decrypt it!

            reader.onload = function(e){

                var decrypted = CryptoJS.AES.decrypt(e.target.result, password)
                                        .toString(CryptoJS.enc.Latin1);

                if(!/^data:/.test(decrypted)){
                    alert("Invalid pass phrase or file! Please try again.");
                    return false;
                }

                a.attr('href', decrypted);
                a.attr('download', file.name.replace('.encrypted',''));

                step(4);
            };

            reader.readAsText(file);
        }

What can I change in above code to allow for larger files to be encrypted and decrypted?

Live site: droplet.so (currently capped at 1.5mb otherwise browser crash is guaranteed)

Kindly thanks in advance.

A Paul
  • 8,113
  • 3
  • 31
  • 61

1 Answers1

2

With a little research I found out that 1.99MB is the maximum the can be saved in the data url in chrome.

Your problem can be done by converting your data url to blob

You can find more information here: Blob from DataURL?

Chrome crashes when URI is too long is here a similar post ( see second answer ).

EDIT:

Possible solution

function dataURItoBlob(dataURI) {
  var byteString = atob(dataURI.split(',')[1]);

  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
  }

  var bb = new BlobBuilder();
  bb.append(ab);
  return bb.getBlob(mimeString);
}

function download(dataURI) {
    var blob = dataURItoBlob(dataURI);
    var url  = window.URL.createObjectURL(blob);
    window.location.assign(url);
}

And you can use this code by calling download(dataURI).

Community
  • 1
  • 1
Deepsy
  • 3,769
  • 7
  • 39
  • 71
  • I been looking into BLOB's but I really have no clue how to implement blobs. Kind of pathetic, but I'm not the best in JS, prob most worst person in JS. – Second Last Jan 01 '14 at 05:54
  • `BlobBuilder` is deprecated. You can use `return new Blob([ab], {type: mimeString});` instead. – Akkumulator Dec 28 '14 at 16:21