我正在将一些服务器端Java代码迁移到一个新的NodeJS服务器。我正在寻找Javascript中的等效方法调用Java的Cipher.doFinal(byte[])请注意,我不能使用NodeJS缓冲区,因为它们不支持负字节值。因此,为了进行加密,我需要一个方法来接受一个正数和负数数组。
这是我目前拥有的与这个问题相关的所有信息:
Node JS/Javascript:var crypto = require('crypto');
var cipher = crypto.createCipher('aes256',key);
Cipher cipher;
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchPaddingException e) {
}try {
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} catch (InvalidKeyException e) {
}
在Java代码后面的中,我调用这个方法,其中Iv表示Initialization Vector:byte[] newIv = cipher.doFinal(myIv);
我怎么能得到相同的结果在JavaScript作为我在doFinal Java方法?
字节处理
你可以使用NodeJS缓冲区。Java中的字节数组可能只由有符号字节组成,但这些字节的处理方式与无符号字节没有任何不同。只有实际比特的值才重要。如果需要直接处理字节,通常最好使用十六进制。您可以通过执行b & 0xFF
将其转换为正整数,也可以通过执行(byte) b
将其转换为正整数。
你当然也可以在NodeJS中做类似的事情来让NodeJS处理带符号的数字,但通常将密钥,IV等视为无符号。
密码选择
现在对于Java AES加密,您正在使用不安全的"AES/ECB/PKCS5Padding"
模式,因为Oracle Java JCE提供程序默认为ECB加密模式和pkcs# 7填充(Java错误地命名为"PKCS5Padding"
)。ECB不使用IV,因此您可以忽略IV的值。奇怪的是,您确实必须使用crypto.createCipheriv(algorithm, key, iv)
作为加密货币。createCipher(algorithm, password)使用密码而不是密钥。当然,你也应该使用"AES-256-ECB"
算法NodeJS/OpenSSL -如果你的密钥确实是256位的大小。
结果是您可以按如下方式放置一个空的IV:
var cipher = require('crypto').createCipheriv('aes-256'ecb', key, '');
至于替换方法,只需将旧的静脉暂时存储为新静脉,然后尝试使用旧的静脉更新新静脉。下面是在NodeJS中使用上面的一些代码创建初始化向量作为缓冲区的样子:
var newIV = oldIV.slice();
newIV = cipher.update(newIV);
oldIV = newIV;