2016-11-18 122 views
0

我需要让用户从他们的系统加载文件,对他们进行即时加密并上传到服务器,并做相反的事情(从服务器上下载文件,实时解密并让用户在本地保存)。虽然AES是首选,但确切的密码方法并不重要。如何在浏览器中使用Javascript加密/解密任意二进制文件?

链接像Encryption/decryption of binary data in the browser只是告诉你“使用CryptoJS”,但我无法找到任何实际工作的样本。我发现所有样本都集中在处理字符串,而在二进制数据中,您可以轻松找到无效的Unicode序列。

是否有任何可以测试哪些可以处理任何类型文件的工作示例?

回答

1

注意:我不会解释如何解密数据,但这应该很容易找出使用代码进行加密和提供的文档链接。

首先,用户必须能够通过input元素选择文件。

<input type="file" id="file-upload" onchange="processFile(event)"> 

然后,您可以加载使用HTML5 FileReader API

function processFile(evt) { 
    var file = evt.target.files[0], 
     reader = new FileReader(); 

    reader.onload = function(e) { 
     var data = e.target.result; 

     // to be continued... 
    } 

    reader.readAsArrayBuffer(file); 
} 

加密使用WebCrypto API所采集的数据文件的内容。
如果您不想随机生成密钥使用crypto.subtle.importKey

// [...] 
var iv = crypto.getRandomValues(new Uint8Array(16)); // Generate a 16 byte long initialization vector 

crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 ]}, false, [ 'encrypt', 'decrypt' ]) 
    .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data)) 
    .then(encrypted => { /* ... */ }); 

现在您可以将加密数据发送到服务器(例如使用AJAX)。 很明显,您还必须以某种方式存储初始化向量,以便以后成功解密所有内容。


这里是一个小例子,它警告加密数据的长度。

注:如果说Only secure origins are allowed,以https重新加载页面,并再次尝试样品(这是WebCrypto API的限制): HTTPS-Link

function processFile(evt) { 
 
    var file = evt.target.files[0], 
 
     reader = new FileReader(); 
 

 
    reader.onload = function(e) { 
 
     var data = e.target.result, 
 
      iv = crypto.getRandomValues(new Uint8Array(16)); 
 
     
 
     crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt']) 
 
      .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data)) 
 
      .then(encrypted => { 
 
       console.log(encrypted); 
 
       alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer 
 
      }) 
 
      .catch(console.error); 
 
    } 
 

 
    reader.readAsArrayBuffer(file); 
 
}
<input type="file" id="file-upload" onchange="processFile(event)">

+0

谢谢。但是,它可以处理大文件吗?在我的测试中,无法在8GB RAM机器上使用Chrome或Firefox处理500 + MB文件。浏览器崩溃。 – Alex

+0

当我玩弄它时,我遇到了同样的问题,但我无法帮助你,对不起。 – schroffl