【问题标题】:Decipher an AES enciphered binary file with Crypto.JS使用 Crypto.JS 解密 AES 加密的二进制文件
【发布时间】:2014-03-17 19:37:16
【问题描述】:

我正在努力实现的目标

我正在开发一个基于浏览器的问答游戏,其中包含预先录制的音频线索,这些线索会发送给用户。为了承担服务器的负载以及已经传输的音频,文件已经在游戏开始之前提前发送给用户。由于游戏是实时和竞争性的,重要的是玩家之前没有机会收听音频文件。我现在的想法是基本上将 AES 加密文件发送给用户,通过 websockets 实时发送文件的密码,在浏览器中使用 crypto.js 对其进行解密并立即播放。

问题

由于某种原因,我无法使用 crypto.js 正确解密二进制文件,因此我可以将其输入音频上下文的 decodeAudioData。我收到来自解密或乱码返回的空响应。

我尝试了什么

音频(在本例中为 mp3)根据文档使用以下调用进行了 AES 加密:

openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"testpass" -e -base64

然后通过带有请求类型文本的 XMLHTTPRequest 加载生成的文件(我已经尝试过 arraybuffer,但也失败了),结果存储在变量中 (this.protectedBuffer)。

根据 Crypto.js 文档,现在应该解密文件:

var decrypted = CryptoJS.AES.decrypt(this.protectedBuffer, 'testpass');
// next step obviously doesn't work as decrypted is
// is not an arraybuffer.
context.decodeAudioData(decrypted, function() { ... }); 

然而,这会导致无法播放,并且只返回一个单词表。我知道我错过了一些步骤,但我现在完全不知道什么不起作用,如果有人能指出我正确的方向并告诉我我做错了什么,我会非常高兴。

编辑:这是我想要达到的目标http://jsfiddle.net/HKu3n/1/

【问题讨论】:

  • 您正在使用 base64 传输它...您是否在传递给 CryptoJS.AES.decrypt 之前对 base64 进行解码?
  • 我什么都试过了。这是我尝试的最新方法:jsfiddle.net/HKu3n/1
  • 我明白了!很快就会有答案....
  • 让它与你的 jsFiddle 一起工作!

标签: javascript aes binaryfiles cryptojs arraybuffer


【解决方案1】:

openssl 生成 base64 编码文件时,会插入大量空格。特别是,它将输出分成 64 字节的行:

U2FsdGVkX18AVcl/JumJawmKlaYWjQwo6wDcETza5AX6VK6aVCMtHXic2xtDIw1G
PJfxbKLJKWgvKXLNGO0jgPTI6qFPllts6VAIzvZ3uqV8BBPd0ge4YJe/q7e7ZGmx
QJyvFnyumo3b2pMxxMWngtl8qpxcsaiSrALnBXZizJ70PcTsyfk7aym1twkj0ofY
...

最后是最后一个换行符。 crypto-js 加密实用程序不喜欢所有这些空白,因此您必须将其删除(我通过拆分/加入来执行此操作)。例如:

$.get('/audio.aes', function(data){
    var decrypted = CryptoJS.AES.decrypt(data.split(/\s/).join(''), 'testpass');
    // ...
});

CryptoJS.AES.decrypt 返回的是一个WordArray 对象。要将其转换为字符串,您必须调用 toString 并提供编码:

decrypted.toString(CryptoJS.enc.Utf8);
decrypted.toString(CryptoJS.enc.Base64);

我手头没有任何音频文件,但我能够通过图像(在/image.aes 提供)使这项工作端到端:

$.get('/image.aes', function(data){
    var decrypted = CryptoJS.AES.decrypt(data.split(/\s/).join(''), 'testpass');
    $('#imageContainer').append('<img src="data:image/jpeg;base64,'
        + decrypted.toString(CryptoJS.enc.Base64) + '">');
    });
});

我在另一端看到了一张图片!您可能需要进行一些争论才能将解码后的数据转换为适合您的音频输出的格式,但我希望这能让您克服困难。

更新

我使用您的音频与您的示例 jsFiddle 一起工作。为了获得必要的ArrayBuffer,我使用了base64DecToArr available here

var decoded = CryptoJS.AES.decrypt(request.response.split(/\s/).join(''),
    'testpass');

var arr = base64DecToArr(decoded.toString(CryptoJS.enc.Base64));
context.decodeAudioData(arr.buffer, function (buffer) {
    alert('success decoding buffer');
}, function (err) {
    alert('couldn\'t decode buffer');
});

在这里工作 jsFiddle:http://jsfiddle.net/BTnpL/

可能有一种更有效的方法可以将从crypto-js 函数返回的WordArray 对象转换为decodeAudioData 使用的ArrayBuffer,但我将把它留给你作为练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多