如何在浏览器中使用Javascript加密/解密任意二进制文件? [英] How can I encrypt/decrypt arbitrary binary files using Javascript in the browser?

查看:1656
本文介绍了如何在浏览器中使用Javascript加密/解密任意二进制文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要让用户从他们的系统加载文件,并将其加密并上传到服务器,并做相反的事情(从服务器下载文件,即时解密,让用户在本地保存) 。确切的密码方法不是很重要,尽管AES是首选。



只是告诉你使用CryptoJS,但是我找不到任何实际工作的样本。我发现的所有样本都集中于处理字符串,而在二进制数据中,您可以轻松找到无效的Unicode序列。



是否有任何可以测试的工作示例可以处理任何

解决方案

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



首先,用户必须能够通过 input 元素

 < input type =fileid =文件上传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;

//要继续...
}

reader.readAsArrayBuffer(file);
}

使用 WebCrypto API

如果您不想随机生成密钥使用 crypto.subtle.importKey

  // [...] 
var iv = crypto.getRandomValues (new Uint8Array(16)); //生成一个16字节长的初始化向量

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

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






这是一个



注意:如果它说只允许安全来源,使用https重新加载页面并再次尝试该示例(这是WebCrypto API的限制):
HTTPS-Link



< class =snippet-code-js lang-js prettyprint-override> 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 '加密的数据''+ encrypted.byteLength +'字节长''(加密的) ); // encrypted是一个ArrayBuffer}).catch(console.error); } reader.readAsArrayBuffer(file); }

 < input type =fileid =文件上传onchange =processFile(event)>  


I need to let users load files from their system, encrypt them on-the-fly and upload to the server and do the opposite thing (download files from the server, decrypt on the fly and let the user save them locally). The exact crypto method is not very important although AES is preferred.

Links like Encryption / decryption of binary data in the browser just tell you "use CryptoJS" but I was unable to find any actually working samples. All samples I found focus on dealing with strings while in binary data you can easily find invalid Unicode sequences.

Is there any working sample I can test which can process files of any kind?

解决方案

Note: I won't explain how to decrypt the data, but that should be rather easy to figure out using the code for encryption and the documentation-links provided.

First of all, the user has to be able to select a file via an input element.

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

You can then load the content of the file using the 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);   
}

Encrypt the acquired data using the WebCrypto API.
If you don't want to randomly generate the key use 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 => { /* ... */ });

Now you can send your encrypted data to the server (e.g. with AJAX). Obviously you will also have to somehow store the Initialization Vector to later successfully decrypt everything.


Here is a little example which alerts the length of the encrypted data.

Note: If it says Only secure origins are allowed, reload the page with https and try the sample again (This is a restriction of the 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)">

这篇关于如何在浏览器中使用Javascript加密/解密任意二进制文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆