类似于Java的Node JS中的AES加密/解密



我正试图在Node JS中复制AES加密和解密Java代码。

Java代码

SecretKeySpec skeySpec;
String key = "a4e1112f45e84f785358bb86ba750f48";
public void encryptString(String key) throws Exception {
try {
skeySpec = new SecretKeySpec(key.getBytes(), "AES");
cipher = Cipher.getInstance("AES");
cipher.init(1, skeySpec);
byte encstr[] = cipher.doFinal(message.getBytes());
String encData = new String(encstr, "UTF-8");
System.out.println(encData);
} catch (NoSuchAlgorithmException nsae) {
throw new Exception("Invalid Java Version");
} catch (NoSuchPaddingException nse) {
throw new Exception("Invalid Key");
}
}

节点JS

var encryptKey = function (text) {
var cipher = crypto.createCipher('aes256', 'a4e1112f45e84f785358bb86ba750f48');
var crypted = cipher.update(text,'utf8', 'hex')
crypted += cipher.final('hex');
console.log(crypted);
return crypted;
}

我无法在NodeJS中获得确切的密文,而我正在Java获得该密文。

在这两种情况下,您的代码实际上使用了不同的加密参数。AES是一种分组密码,它采用:要加密的明文、初始化向量,也称为IV(与明文一起使用(和加密密钥。

在Java中,IV显然是在init((上自动生成的,它来自Cipher.init:的Java SE平台文档

可以使用getParameters或getIV检索生成的参数(如果参数是IV(。

在Node.js中,如果使用不推荐使用的createCipher函数,IV将根据提供的密钥自动生成,其方式可能与Java不同,因此您将获得不同的密文。但是,您应该使用不推荐使用的变体crypto.createCipheriv:https://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options

为了准确地再现密文,您应该:

  • 在双方使用相同的加密算法-最好准确地指定此加密算法,例如aes-256-cbc,或通过身份验证的加密方案,如aes-256-gcm。后者更难使用,但提供消息身份验证
  • 在两侧使用相同的IV,方法是在Java中的初始化参数中提供,并在Node中使用createCipheriv;不过要小心,在生产中你应该总是把它随机化!看见https://stackoverflow.com/a/20888967/6098312

作为结束语,当使用块加密时,通常会生成安全的随机IV,这意味着即使是相同的明文,密文也总是不同的。这是一件好事!它保护您的有效负载不受攻击者的攻击,攻击者会观察加密数据并根据消息重复得出结论。

最后,在查看Java文档Node JS Crypto文档后,终于得到了结果。我们必须使用crypto.createCipheriv()而不是带有iv的crypto.createCipher。这里iv将是null

代码:

let crypto = require('crypto');
var iv = new Buffer.from('');   //(null) iv 
var algorithm = 'aes-256-ecb';
var password = 'a4e1112f45e84f785358bb86ba750f48';      //key password for cryptography
function encrypt(buffer){
var cipher = crypto.createCipheriv(algorithm,new Buffer(password),iv)
var crypted = Buffer.concat([cipher.update(buffer),cipher.final()]);
return crypted;
}
console.log(encrypt(new Buffer('TextToEncrypt')).toString())

最新更新