首先,让我首先说明我不是一个密码学家,我也不擅长编写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兼容.任何帮助将非常感激.
我如何使用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 实现有很多感觉很复杂的步骤(比如生成实际使用的密钥),因为他们知道如何进行加密,并且只是以正确的方式进行。