与NodeJ和mbedtls一起使用的加密程序

Che*_*603 5 c aes node.js

首先,让我首先说明我不是一个密码学家,我也不擅长编写c代码,所以如果这个问题的答案显而易见或得到回答,请原谅.我正在开发一个消息传递程序,不能在目标平台上使用TLS.因此,我需要找到一种使用对称预共享密钥密码(如AES)加密每条消息的方法.

我正在寻找一种方法来加密和解密一端的mbedtls程序(例如aescrypt2)和另一端的nodejs程序之间的数据.Mbedtls,以前的polarssl,是一个为嵌入式设备提供加密的库.源代码中包含一些示例程序,如aescrypt2,rsaencrypt,ecdsa和crypt_and_hash.

当使用aescrypt2对生成的加密数据进行解密时,Aescrypt2工作正常,但我似乎无法使用aescrypt加密数据,使用nodejs加密或任何其他程序解密,包括openssl.例如:

echo 'this is a test message' >test.txt
aescrypt 0 test.txt test.out hex:E76B2413958B00E193
aescrypt 1 test.out test.denc hex:E76B2413958B00E193
cat test.denc
this is a test message
Run Code Online (Sandbox Code Playgroud)

使用openssl:

openssl enc -in out.test -out outfile.txt -d -aes256 -k E76B2413958B00E193
bad magic number
Run Code Online (Sandbox Code Playgroud)

一些当前不起作用的示例节点代码

    var crypto = require('crypto');
    var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
    encryptdata = new Buffer(encryptdata, 'base64').toString('binary');

    var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv),
        decoded = decipher.update(encryptdata, 'binary', 'utf8');

    decoded += decipher.final('utf8');
    return decoded;
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
    var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv),
         encryptdata = encipher.update(cleardata, 'utf8', 'binary');

    encryptdata += encipher.final('binary');
    encode_encryptdata = new Buffer(encryptdata, 'binary').toString('base64');
    return encode_encryptdata;
}

var cryptkey   = crypto.createHash('sha256').update('Nixnogen').digest(),
    iv         = 'a2xhcgAAAAAAAAAA',
    buf        = "Here is some data for the encrypt", // 32 chars
    enc        = AESCrypt.encrypt(cryptkey, iv, buf);
    var dec        = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc);
console.warn("decrypt all: " + dec);
Run Code Online (Sandbox Code Playgroud)

这会导致每次都出现错误或垃圾文本.我也试过调整各种各样的东西.

我已经尝试了一百种不同的方法,包括使用-pass pass:passwordarg无济于事.使用nodejs,我得到了解密错误,或者在解密时出现乱码.我尝试过在网上学习很多教程,比如这篇教程,以及这个帖子的建议,以及我能找到的其他一切.我已经读过不同的加密程序使用不同的标准,因此并不总能保证跨平台/程序/语言的兼容性,但我想有人之前已经处于这种预测中,并且知道解决方案吗?

我如何使用nodejs解密由aescrypt2(或类似程序)加密的数据?我只能使用系统exec调用使节点执行aescrypt2来解密/加密数据,这是不理想的,因为它会大大减慢速度.我愿意使用与aescrypt2不同的程序.唯一的要求是它必须在Linux上运行,不能使用openssl libs(因为它们在目标系统上不受支持),由于空间限制,程序应该小而简单,并且最重要的是,加密/解密需要是与nodejs兼容.任何帮助将非常感激.

gra*_*hel 2

我如何使用nodejs解密由aescrypt2(或类似程序)加密的数据?

抱歉,但没有比这更好的答案了:通过执行与 aescrypt2 解密文件时完全相同的操作。您已自行链接到源,因此只需在 node.js 中执行与解密分支中 C 中相同的步骤即可。

首先,熟悉包含加密数据的文件的布局

    /*
     *  The encrypted file must be structured as follows:
     *
     *        00 .. 15              Initialization Vector
     *        16 .. 31              AES Encrypted Block #1
     *           ..
     *      N*16 .. (N+1)*16 - 1    AES Encrypted Block #N
     *  (N+1)*16 .. (N+1)*16 + 32   HMAC-SHA-256(ciphertext)
     */
Run Code Online (Sandbox Code Playgroud)

因此,您需要从文件中提取 IV、加密块和 HMAC,而不是像尝试使用 openssl 那样尝试解密整个内容(您的 openssl 示例也没有使用正确的 IV,而是尝试从密钥中派生它提供 - 阅读手册页)。

接下来,拿到正确的钥匙。用于加密/解密的实际密钥不是命令行上提供的密钥,而是使用 SHA256 使用命令行上传递的密钥对 IV 进行 8192 次哈希迭代。

最后,他们使用 AES-256-ECB(您的 openssl 和 node.js 示例使用 CBC!)每 16 个字节进行解密,并将结果与​​前 16 个字节进行异或(IV 用于前 16 个字节)。

也许还有更多内容,我只是列出了我在阅读 aescrypt2.c 代码时看到的最明显的事情。

所以我的建议是:尝试在 Node.js 中编写相同的逻辑,并尝试找到相应 mbedtls 对应项的 Node.js 加密调用。

我不是加密专家,但我敢打赌,aescrypt 实现有很多感觉很复杂的步骤(比如生成实际使用的密钥),因为他们知道如何进行加密,并且只是以正确的方式进行。