如何在浏览器中使用Javascript加密/解密任意二进制文件?

时间:2016-11-18 15:13:08

标签: javascript encryption cryptojs

我需要让用户从他们的系统加载文件,即时加密它们并上传到服务器并执行相反的操作(从服务器下载文件,动态解密并让用户在本地保存) 。尽管AES是首选,但确切的加密方法并不是很重要。

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

我可以测试哪些工作样本可以处理任何类型的文件?

2 个答案:

答案 0 :(得分:5)

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

首先,用户必须能够通过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.deriveKey创建密钥,例如,根据用户输入的密码。

// [...]
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

&#13;
&#13;
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);   
}
&#13;
<input type="file" id="file-upload" onchange="processFile(event)">
&#13;
&#13;
&#13;

答案 1 :(得分:2)

有关显示基于https://github.com/meixler/web-browser-based-file-encryption-decryption的示例,该示例显示了在Web浏览器中使用Javascript对任意二进制文件进行加密/解密的示例,请参见Web Crypto API