3

我正在将一些服务器端 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 方法中相同的结果?

4

2 回答 2

3

字节处理

可以使用 NodeJS 缓冲区。Java 中的字节数组可能只包含有符号字节,但这些字节的处理方式与无符号字节没有任何不同。只有实际位的值很重要。如果您需要直接处理字节,通常最好使用十六进制。您可以通过 perform 转换为正整数值,b & 0xFF也可以通过 perform 执行相反的操作(byte) b

你当然也可以在 NodeJS 中做类似的事情来让 NodeJS 处理有符号的数字,但是通常将密钥、IV 等视为无符号的。

密码选择

现在对于 Java AES 加密,您使用的是不安全模式,因为 Oracle Java JCE 提供程序默认为 ECB 加密模式和 PKCS#7 填充(Java 错误地命名)。ECB 不使用 IV,因此您可以忽略 IV 的值。奇怪的是,您必须使用crypto.createCipher (algorithm, password)使用密码而不是密钥。当然,您还应该使用NodeJS/OpenSSL 的算法——如果您的密钥确实是 256 位大小。"AES/ECB/PKCS5Padding""PKCS5Padding"crypto.createCipheriv(algorithm, key, iv)"AES-256-ECB"

于 2014-07-06T11:31:39.033 回答
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;

于 2014-07-10T03:43:10.693 回答