【Node.Js】【 AES加密】 aes-128-ecb 加密后与其他程序加密出来后不相符 , 秘钥Key和秘钥向量IV 出现异常
发布于 8 年前 作者 Relax-ji 13727 次浏览 来自 问答

-----------------先贴代码--------------------------- var crypto = require(‘crypto’); var data = “156156165152165156156”; console.log('Original cleartext: ’ + data); var algorithm = ‘aes-128-ecb’; var key = ‘78541561566’; var clearEncoding = ‘utf8’; var iv = “”; //var cipherEncoding = ‘hex’; //If the next line is uncommented, the final cleartext is wrong. var cipherEncoding = ‘base64’; var cipher = crypto.createCipheriv(algorithm, key,iv);

var cipherChunks = [];
cipherChunks.push(cipher.update(data, clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
console.log(cipherEncoding + ' ciphertext: ' + cipherChunks.join(''));

var decipher = crypto.createDecipheriv(algorithm, key,iv);
var plainChunks = [];
for (var i = 0;i < cipherChunks.length;i++) {
  plainChunks.push(decipher.update(cipherChunks[i], cipherEncoding, clearEncoding));

}
plainChunks.push(decipher.final(clearEncoding));
console.log("UTF8 plaintext deciphered: " + plainChunks.join(''));

----------------------------end-----------------------------
按照上面的方式,做加密是可以过的
  但是当我加上别人的AES加密配置后(要解密他们的),就不行了 (他们用的是C#)

-----------------别人的配置数据------------------------

加密方式 AES 运算模式 ECB 块大小 128(位) 填充模式 零字节组成的字符串 密钥向量 { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF } 密钥 89622015104709087435617163207900 编码 UTF8 密文传输编码 BASE64 样例 明文:123456 密文:0cfAwa9X9XRpr53SKjfiug== (改数据配置,我用C#代码校验过,是可以通过的,与样例匹配)

按照该配置处理,会出现以下三个问题 Key='89622015104709087435617163207900’ IV=[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF] 1、TypeError: Not a buffer at TypeError (native) at new Cipheriv (crypto.js:187:16) at Object.Cipheriv (crypto.js:185:12) at Object.exports.AESEncrypt (d:\Node Work\MemberConduct\Tools\AES_KeChuan.js:23:23) at d:\Node Work\MemberConduct\routes\index.js:20:23 at Layer.handle [as handle_request] (d:\Node Work\MemberConduct\node_modules\express\lib\router\layer.js:95:5) at next (d:\Node Work\MemberConduct\node_modules\express\lib\router\route.js:131:13) at Route.dispatch (d:\Node Work\MemberConduct\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (d:\Node Work\MemberConduct\node_modules\express\lib\router\layer.js:95:5) at d:\Node Work\MemberConduct\node_modules\express\lib\router\index.js:277:22

当我将IV转成buffer后,会出现以下问题 2、 Invalid IV length Error: Invalid IV length at Error (native) at new Cipheriv (crypto.js:187:16) at Object.Cipheriv (crypto.js:185:12) at Object.exports.AESEncrypt (d:\Node Work\MemberConduct\Tools\AES_KeChuan.js:23:23) at d:\Node Work\MemberConduct\routes\index.js:20:23 at Layer.handle [as handle_request] (d:\Node Work\MemberConduct\node_modules\express\lib\router\layer.js:95:5) at next (d:\Node Work\MemberConduct\node_modules\express\lib\router\route.js:131:13) at Route.dispatch (d:\Node Work\MemberConduct\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (d:\Node Work\MemberConduct\node_modules\express\lib\router\layer.js:95:5) at d:\Node Work\MemberConduct\node_modules\express\lib\router\index.js:277:22

尝试按照例子代码中的IV=’’,会出现第三个问题 3、Invalid key length

npm 上搜索过好几个aes库,但是与数据配置都不符合, 有用Node做过这方面的,麻烦指点一下,不甚感激

4 回复

/**

  • aes加密
  • @param data
  • @param secretKey
  • @param secretIV */ exports.aesEncrypt = function(data, secretKey, iv) { try{ var cipherEncoding = ‘base64’;//有可能是base64 var clearEncoding = ‘utf8’; var cipher = crypto.createCipheriv(‘aes-128-cbc’,secretKey, iv); return cipher.update(data,clearEncoding,cipherEncoding) + cipher.final(cipherEncoding); }catch(e){ logger.error('aesEncrypt error: ’ + err); return ‘’; }

}

/**

  • aes解密
  • @param data
  • @param secretKey
  • @param secretIV
  • @returns {*} */ exports.aesDecrypt = function(data, secretKey, iv) { try{ var cipherEncoding = ‘base64’;//有可能是base64 var clearEncoding = ‘utf8’; var cipher = crypto.createDecipheriv(‘aes-128-cbc’,secretKey, iv); return cipher.update(data,cipherEncoding,clearEncoding) + cipher.final(clearEncoding); }catch(err){ logger.error('aseDecrypt error: ’ + err); return ‘’; } }

这个是我用的,和php的aes能对上,已经在用

AES算法,key的长度必须是128位,也就是16 byte,buffer的长度必须为16,因为这是AES的一个数据块长度。 AES在CBC/PKCS5Padding模式下,使用的向量长度也是16 byte。 问题2和问题3都是长度不匹配的问题

另外,ECB模式下是没有加密向量的,只有CBC模式才有加密向量。C#的数据给的貌似是ECB

还有一个需要注意的是,每个平台秘钥生成策略可能不一样,同一个string生成的buffer可能不同。保险的方法是确保秘钥buffer是相同的

@TakWolf 确实这样的 现在的问题就是C#加密出来的确实可以,但Node就是无法实现, 按照上面的配置数据,得使用 aes-256-cbc模式才可以,但是加密出来的内容与样例不一致 -------------------------贴C#代码------------------------------------ public class AESEncryption { private static byte[] _key1 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; const string key = “89622015104709087435617163207900”; //加密 public static string AESEncrypt(string plainText) { if (!string.IsNullOrEmpty(plainText)) { SymmetricAlgorithm des = Rijndael.Create(); byte[] inputByteArray = Encoding.UTF8.GetBytes(plainText); des.Key = Encoding.UTF8.GetBytes(key); des.IV = _key1; des.BlockSize = 128; des.Padding = PaddingMode.Zeros; des.Mode = CipherMode.ECB; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); } byte[] cipherBytes = ms.ToArray(); return Convert.ToBase64String(cipherBytes); } } else return string.Empty; } //解密 public static string AESDecrypt(string cipherText) { if (!string.IsNullOrEmpty(cipherText)) { byte[] buffer = Convert.FromBase64String(cipherText);

    SymmetricAlgorithm des = Rijndael.Create();
    des.Key = Encoding.UTF8.GetBytes(key);
    des.IV = _key1;
    des.BlockSize = 128;
    des.Padding = PaddingMode.Zeros;
    des.Mode = CipherMode.ECB;
    byte[] decryptBytes = new byte[cipherText.Length];
    using (MemoryStream ms = new MemoryStream(buffer))
    {
      using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read))
      {
        cs.Read(decryptBytes, 0, decryptBytes.Length);
      }
      return Encoding.UTF8.GetString(decryptBytes).TrimEnd('\0');
    }
  }
  else return string.Empty;
}

}

我是来看楼主头像的 <br> <br>来自吊吊的 <a href=“https://github.com/ihanyang/cnode-vue”>cnode-vue</a>

回到顶部