我正在将一些服务器端Java代码迁移到新的NodeJS服务器。 我正在寻找Javascript中的等效方法调用到Java的Cipher.doFinal(byte []) 请注意,我不能使用NodeJS缓冲区,因为它们不支持负字节值。所以要进行加密,我需要一个接受正数和负数数组的方法。
以下是我目前所有与此问题相关的内容:
节点JS / Javascript:
var crypto = require('crypto');
var cipher = crypto.createCipher('aes256',key);
Java(javax.crypto.Cipher):
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表示初始化向量:
byte[] newIv = cipher.doFinal(myIv);
如何在JavaScript中获得与doFinal Java方法相同的结果?
答案 0 :(得分:2)
你可以使用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)
,因为crypto.createCipher(algorithm, password)使用密码而不是密钥。当然,对于NodeJS / OpenSSL,你也应该使用算法"AES-256-ECB"
- 如果你的密钥确实是256位大小。
答案 1 :(得分:2)
原来你可以按如下方式放置一个空的IV:
var cipher = require('crypto').createCipheriv('aes-256'ecb', key, '');
至于替换方法,只需将旧IV暂时存储为新IV,然后尝试使用旧IV更新新IV。以下是在NodeJS中使用上面创建的缓冲区初始化向量的一些代码时的样子:
var newIV = oldIV.slice();
newIV = cipher.update(newIV);
oldIV = newIV;