2014-08-31 37 views
0

这里的目标是上传文件,在客户端对其进行加密,然后通过AJAX将文件及其属性发送到myphpscript.php。为了允许更大的文件,我希望使用FileReader切片方法以片段形式上传,并使用CryptoJS站点(https://code.google.com/p/crypto-js/)上描述的方法逐步加密切片。我的代码在下面运行,但最终只能存储预期的整个加密文件的一小部分。我可以按照我描述的方式逐步上传和加密吗?使用CryptoJS进行上传和加密

<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script> 
<script src="js/aes.js"></script> 
<script> 
    function readBlob(opt_startByte, opt_stopByte) { 

     var files = document.getElementById('fileinput').files; 
     if (!files.length) { 
      alert('Please select a file!'); 
      return; 
     } 

     var file = files[0]; 
     var start = parseInt(opt_startByte) || 0; 
     var stop = parseInt(opt_stopByte) || file.size - 1; 

     var reader = new FileReader(); 

     // If we use onloadend, we need to check the readyState. 
     reader.onloadend = function(evt) { 
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2 
       window.bits.push(aesEncryptor.process(evt.target.result)); 
      } 
     }; 

     var blob = file.slice(start, stop + 1); 
     reader.readAsBinaryString(blob); 
    } 

    function handling(evt) { 

     // INITIALIZE PROGRESSIVE ENCRYPTION 
     var key = CryptoJS.enc.Hex.parse(document.getElementById('pass').value); 
     var iv = CryptoJS.lib.WordArray.random(128/8); 
     window.bits = []; 
     window.aesEncryptor = CryptoJS.algo.AES.createEncryptor(key, {iv: iv}); 

     // LOOP THROUGH BYTES AND PROGRESSIVELY ENCRYPT 
     var startByte = 0; 
     var endByte = 0; 
     while(startByte < document.querySelector('input[type=file]').files[0].size - 1){ 
      endByte = startByte + 1000000; 
      readBlob(startByte, endByte); 
      startByte = endByte; 
     } 

     // FINALIZE ENCRYPTION AND UPLOAD 
     var encrypted = aesEncryptor.finalize(); 
     encrypted = encodeURIComponent(encrypted); 
     var filename = document.getElementById('fileinput').value; 
     var file_type = document.getElementById('fileinput').files[0].type; 
     var url = 'data=' + encrypted + '&filename=' + filename + '&filetype=' + file_type; 
     $.ajax({ 
      url: 'myphpscript.php', 
      type: 'POST', 
      data: url 
     }).success(function(data){ 
      // Display encrypted data 
      document.getElementById('status').innerHTML = 'Upload Complete.'; 
     }); 
     alert(encrypted); 

    } 
</script> 
+0

如果你想上传数据块中的数据,那么我希望看到你在某种循环中发出请求......但是我没有看到这种情况发生? – CBroe 2014-08-31 15:51:33

+0

现在我正在这样做,纠正我,如果我错了,是在部分评论“循环通过字节和进步加密”。在while循环中,我运行读取特定片的函数readBlob。 – Alek 2014-08-31 15:54:12

+0

但是,您将数据发送到该环路以外的服务器,之后... – CBroe 2014-08-31 15:58:53

回答

0

所以你的问题是该行var encrypted = aesEncryptor.finalize();

这是不加密的文件,而是由CryptoJS.AES终结产生的最后的“块”。

您需要将其追加到window.bits缓冲区的末尾以生成完全加密的文件。

而且,你不应该使用window.bits.push,你应该保持这样的(伪代码)的引用,以每块的保持:

var prog; 
//then in the loop, if chunk is null assign to chunk or else concat: 
loop: 
    if(!prog) 
     prog = cipher.process() 
    else 
     prog.concat(cipher.process()) 

//then finalize 
prog.concat(cipher.finalize()) 

//now you're free to do whatever with the encrypted file: 
var ciphertext = prog.toString() 
0

一个重要的事情要记住的是,大块可能无法到达加密器因此您必须跟踪大块进入aesEncryptor.process的顺序,以便您可以稍后以正确的顺序解密对块进行排队并按照正确的顺序对它们进行加密以开始用。

+0

是的,我详细说明了如何做到这一点[http://craig-bruce.com/progressive -decryption /) – 2015-03-29 23:13:54

相关问题