我正在尝试使用node.js使用aes-128-cbc解密一些数据。当我使用在线工具进行相同的解密时,它可以正常工作,但是以某种方式我的node.js代码存在一些我无法查明的错误,解密的结果无效。
以下是在线工具的工作屏幕截图。效果很好
这是我的代码存在问题
'''
var encData = '2WSGjqFJJ0Zxl7Ao6uT9+CpESHBPz+ejTlzPN+ELPtdFbL2cr3hJo/NM2XJXt1UKefdyJFjPxz//suRHM7PyorNtoVAoP8hdbcUndUtFEOpUihzVcllffRI3aoQ57iD5+5NZQEAncDwY/+fve/ocOCgBGJMRGN6CvjSJ9dIKFD2L0u452oBoMFBdkdNEslFabXFTxBut95BO1H+itJjOFCb9pQh0mK9HetzmUMjX7PZ55LysZRvddAracs7Fj3Jc';
var buf = Buffer.from(encData);
var encDataBase64 = buf.toString('base64');
var key = '6bhgdu99954paut6'; //dummy key for stackoverflow question
var mykeydec = crypto.createDecipher('aes-128-ecb', key);
mykeydec.setAutoPadding(false);
var mystrdec = mykeydec.update(encDataBase64, 'base64', 'ascii');
mystrdec += mykeydec.final("ascii"); //?
console.log("dec data", mystrdec);
'''
答案 0 :(得分:2)
NodeJS代码有几个问题:首先,使用createDecipher
代替createDecipheriv
。 createDecipher
(同时不建议使用)将第二个参数解释为密码并从中生成密钥,而CreateDecipheriv
直接将第二个参数解释为密钥。
第二,在创建缓冲区buf
时,必须使用编码(此处为base64
)。但是,由于update
方法也可以处理字符串(此处的第二个参数指定输入编码),因此可以省略此步骤。
最后,使用PKCS7-padding对数据进行加密,这是默认的填充,因此不能禁用它进行解密。
通过以下更改可以解密密文:
var crypto = require('crypto');
var encData = '2WSGjqFJJ0Zxl7Ao6uT9+CpESHBPz+ejTlzPN+ELPtdFbL2cr3hJo/NM2XJXt1UKefdyJFjPxz//suRHM7PyorNtoVAoP8hdbcUndUtFEOpUihzVcllffRI3aoQ57iD5+5NZQEAncDwY/+fve/ocOCgBGJMRGN6CvjSJ9dIKFD2L0u452oBoMFBdkdNEslFabXFTxBut95BO1H+itJjOFCb9pQh0mK9HetzmUMjX7PZ55LysZRvddAracs7Fj3Jc';
//var buf = Buffer.from(encData);
//var encDataBase64 = buf.toString('base64');
var key = '<your obfuscated secret key>';
//var mykeydec = crypto.createDecipher('aes-128-ecb', key); // Use createDecipheriv
var mykeydec = crypto.createDecipheriv('aes-128-ecb', key, null);
//mykeydec.setAutoPadding(false); // Don't disable PKCS7-Padding
//var mystrdec = mykeydec.update(encDataBase64, 'base64', 'ascii'); // Decrypt the Base64-encoded ciphertext directly
var mystrdec = mykeydec.update(encData, 'base64', 'ascii');
mystrdec += mykeydec.final("ascii");
console.log("dec data", mystrdec);
此外:您在问题中透露了太多信息,以至于我在几分钟内就能找到您的混淆密钥,这就是为什么我能够解密您的密文并因此验证我的密文的原因代码更改。换句话说,此密钥已被盗用,不再可以使用!
答案 1 :(得分:0)
我不确定您的确切问题是什么。可能有很多事情。 数据如何加密?字符串的长度是块大小的倍数吗?
如果不是这种情况,可能需要填充。
在此示例中,一切正常:
const crypto = require("crypto");
//Encrypt
const data = "{\"msg\":\"This data should be protected at all cost! But it is pretty long, so you need to use all chunks...\"}";
const key = "SecretKeyOfExactlyAndOnly32Bytes";
const chunks = [];
const encoder = crypto.createCipher("aes-128-ecb", Buffer.from(key));
encoder.setAutoPadding(true); // This does not match the block size, so padding is needed...
chunks.push(encoder.update(data).toString("base64"));
chunks.push(encoder.final().toString("base64"));
let cipherText = chunks.join("");
console.log("\nCiphertext: ", cipherText,"\n");
//Decrypt
let decoder = crypto.createDecipher("aes-128-ecb", key);
decoder.setAutoPadding(true); // setting this to false yields garbage data on the end because of padding...
let clearText = decoder.update(cipherText, "base64", "ascii");
clearText += decoder.final().toString("ascii");
console.log("\nClear Text: ", clearText);
//Verify Valid JSON
console.log(JSON.parse(clearText).msg);