与 NodeJs 和 mbedtls 一起工作的加密程序
Encryption Program That Works With NodeJs and mbedtls
首先声明一下,我不是密码学家,我也不是很擅长写c代码,所以如果这个问题的答案很明显或者有答案,请原谅。我正在开发消息程序,无法在目标平台上使用 TLS。因此,我需要找到一种使用对称预共享密钥密码(如 AES)加密每条消息的方法。
我正在寻找一种在一端的 mbedtls 程序(例如 aescrypt2)和另一端的 nodejs 程序之间加密和解密数据的方法。 Mbedtls,以前称为 polarssl,是一个为嵌入式设备提供加密的库。源代码中包含一些示例程序,如 aescrypt2、rsaencrypt、ecdsa 和 crypt_and_hash.
当生成的加密数据也使用 aescrypt2 解密时,Aescrypt2 工作正常,但我似乎无法使用 aescrypt 加密数据以使用 nodejs crypto 或与此相关的任何其他程序(包括 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
使用 openssl:
openssl enc -in out.test -out outfile.txt -d -aes256 -k E76B2413958B00E193
bad magic number
一些当前不起作用的示例节点代码
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);
这每次都会导致错误或垃圾文本。我也尝试过调整各种东西。
我已经尝试了一百种不同的方法,包括使用 -pass pass:password
参数都无济于事。使用 nodejs,我要么得到错误的解密错误,要么在解密时出现乱码。我已经尝试按照网上的许多教程进行操作,例如 this one, and suggestions from this thread,以及我能找到的所有其他内容。我读到过不同的加密程序使用不同的标准,因此 platforms/programs/languages 之间的兼容性并不总是得到保证,但我想有人曾经陷入过这种困境并且知道解决方案?
我如何使用 nodejs 解密由 aescrypt2(或类似程序)加密的数据?我只能使用系统 exec 调用并让节点对 decrypt/encrypt 数据执行 aescrypt2 来使其工作,这并不理想,因为它会大大减慢速度。我愿意使用与 aescrypt2 不同的程序。唯一的要求是它必须 运行 on Linux,不能使用 openssl 库(因为它们在目标系统上不受支持),程序应该小而简单,由于 space限制,最重要的是,encryption/decryption 需要与 nodejs 兼容。任何帮助将不胜感激。
How would I, using nodejs, decrypt data encrypted by aescrypt2 (or a program like it)?
很抱歉,没有比解密文件时 aescrypt2 所做的完全相同的事情更好的答案了。您已经自己链接到源代码,所以只需在 node.js 中执行与解密分支中 C 中相同的步骤即可。
首先,熟悉layout of the file containing the encrypted data:
/*
* 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)
*/
因此您需要从文件中提取 IV、加密块和 HMAC,而不是像您尝试使用 openssl 那样尝试解密整个文件(您的 openssl 示例也没有使用正确的 IV,而是尝试从提供的密钥派生它 - 阅读 man page)。
接下来,拿到钥匙。 actual key used 到 encrypt/decrypt 不是命令行上提供的,而是使用 SHA256 使用命令行上传递的密钥对 IV 进行 8192 次散列迭代。
最后,他们使用 AES-256-ECB(您的 openssl 和 node.js 示例使用 CBC!)解密,每 16 个字节和 XOR the result 使用前面的 16 个字节(使用 IV前 16 个字节)。
可能还有更多内容,我只是列出了我在通读 aescrypt2.c 代码时看到的最明显的东西。
所以我的建议是:尝试在 node.js 中编写相同的逻辑,并尝试为相应的 mbedtls 对应项找到 node.js 加密调用。
我不是加密专家,但我敢打赌,aescrypt 的实现有很多步骤,感觉很复杂(比如生成实际使用的密钥),因为他们知道如何进行加密,而且做得正确方法。
首先声明一下,我不是密码学家,我也不是很擅长写c代码,所以如果这个问题的答案很明显或者有答案,请原谅。我正在开发消息程序,无法在目标平台上使用 TLS。因此,我需要找到一种使用对称预共享密钥密码(如 AES)加密每条消息的方法。
我正在寻找一种在一端的 mbedtls 程序(例如 aescrypt2)和另一端的 nodejs 程序之间加密和解密数据的方法。 Mbedtls,以前称为 polarssl,是一个为嵌入式设备提供加密的库。源代码中包含一些示例程序,如 aescrypt2、rsaencrypt、ecdsa 和 crypt_and_hash.
当生成的加密数据也使用 aescrypt2 解密时,Aescrypt2 工作正常,但我似乎无法使用 aescrypt 加密数据以使用 nodejs crypto 或与此相关的任何其他程序(包括 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
使用 openssl:
openssl enc -in out.test -out outfile.txt -d -aes256 -k E76B2413958B00E193
bad magic number
一些当前不起作用的示例节点代码
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);
这每次都会导致错误或垃圾文本。我也尝试过调整各种东西。
我已经尝试了一百种不同的方法,包括使用 -pass pass:password
参数都无济于事。使用 nodejs,我要么得到错误的解密错误,要么在解密时出现乱码。我已经尝试按照网上的许多教程进行操作,例如 this one, and suggestions from this thread,以及我能找到的所有其他内容。我读到过不同的加密程序使用不同的标准,因此 platforms/programs/languages 之间的兼容性并不总是得到保证,但我想有人曾经陷入过这种困境并且知道解决方案?
我如何使用 nodejs 解密由 aescrypt2(或类似程序)加密的数据?我只能使用系统 exec 调用并让节点对 decrypt/encrypt 数据执行 aescrypt2 来使其工作,这并不理想,因为它会大大减慢速度。我愿意使用与 aescrypt2 不同的程序。唯一的要求是它必须 运行 on Linux,不能使用 openssl 库(因为它们在目标系统上不受支持),程序应该小而简单,由于 space限制,最重要的是,encryption/decryption 需要与 nodejs 兼容。任何帮助将不胜感激。
How would I, using nodejs, decrypt data encrypted by aescrypt2 (or a program like it)?
很抱歉,没有比解密文件时 aescrypt2 所做的完全相同的事情更好的答案了。您已经自己链接到源代码,所以只需在 node.js 中执行与解密分支中 C 中相同的步骤即可。
首先,熟悉layout of the file containing the encrypted data:
/*
* 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)
*/
因此您需要从文件中提取 IV、加密块和 HMAC,而不是像您尝试使用 openssl 那样尝试解密整个文件(您的 openssl 示例也没有使用正确的 IV,而是尝试从提供的密钥派生它 - 阅读 man page)。
接下来,拿到钥匙。 actual key used 到 encrypt/decrypt 不是命令行上提供的,而是使用 SHA256 使用命令行上传递的密钥对 IV 进行 8192 次散列迭代。
最后,他们使用 AES-256-ECB(您的 openssl 和 node.js 示例使用 CBC!)解密,每 16 个字节和 XOR the result 使用前面的 16 个字节(使用 IV前 16 个字节)。
可能还有更多内容,我只是列出了我在通读 aescrypt2.c 代码时看到的最明显的东西。
所以我的建议是:尝试在 node.js 中编写相同的逻辑,并尝试为相应的 mbedtls 对应项找到 node.js 加密调用。
我不是加密专家,但我敢打赌,aescrypt 的实现有很多步骤,感觉很复杂(比如生成实际使用的密钥),因为他们知道如何进行加密,而且做得正确方法。