java - Java 和 Node 之间的加密不一致

标签 java node.js encryption aes cbc-mode

我正在尝试在 Node.js 中复制基于 Java 的加密方案,但不幸的是我得到的结果不一致。

这是 Java 方法:

private Transfer encrypt(byte[] salt, String ticketNumber, String data) throws Exception {
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(ticketNumber.toCharArray(), salt, 1000, 128);
    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    String encoded = java.util.Base64.getEncoder().encodeToString(secret.getEncoded());
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] iv ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    IvParameterSpec ips = new IvParameterSpec(iv);
    cipher.init(Cipher.ENCRYPT_MODE, secret, ips);
    AlgorithmParameters params = cipher.getParameters();
    Transfer myRetVal =  new Transfer();
    byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();

    //Set some decrypt information
    myRetVal.setIv(Base64.encodeBase64String(ivBytes));
    //Set the attendee data
    myRetVal.setData(Base64.encodeBase64String(cipher.doFinal(data.getBytes())));
    //Set the hashed Ticket number
    myRetVal.setTicketNumberHashed(Base64.encodeBase64String(getHash(hashIterations, ticketNumber, salt)));
    return myRetVal;
}

还有我的 Node 版本:

exports.getEncryptedString = function(salt, password, data) {
  var iv = new Buffer('0000000000000000');
  var key = crypto.pbkdf2Sync(password, salt, 1000, 16, 'sha1');
  var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
  return cipher.update(data, 'utf8', 'base64') + cipher.final('base64');
};

当我向两个函数传递字符串“SomeJSON”和相同的 key 时,我得到了不同的加密结果。

来自 Java:ENnQzWowzrl7LQchRmL7sA== 来自 Node :TGreJNmQH92gHb1bSy4xAA==

我无法弄清楚我的 Node 实现有什么不同。

最佳答案

new Buffer('0000000000000000')默认使用utf8编码,但是UTF-8中的"0"是字节0x30 而在 Java 中,您使用 0x00 字节作为 IV。你想要的是

var iv = new Buffer('00000000000000000000000000000000', 'hex');

var iv = new Buffer(16);
iv.fill(0);

完成测试后,您应该更改程序,为每次加密生成一个新的 IV。 IV 不必是 secret 的,因此您可以简单地将其添加到密文中。当你想稍后解密它时,你可以将 IV 切掉(AES 为 16 字节)并在解密期间使用它。

关于java - Java 和 Node 之间的加密不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31012727/

相关文章:

java - 使用开放式套接字在 Tomcat 上进行并行部署?

javascript - Node JS 从文件中加载 JSON 数组

java - IntelliJ IDE 禁用 'is never used' 检查

java - JPA:根据实例变量动态地将实体映射到表

node.js - 将 shapefile 和 geoJson 转换为 TopoJson 和/或使用 geo2topo

javascript - 如何在我的 HTML 文档中初始化此插件?

java - 在哪里保存 Android 应用程序中的电子邮件密码(使用 JavaMail API)?

java - Java 中的 AES-256 加密需要多大的初始化 vector ?

encryption - 如何将 256 位公钥编码为可变长度的字序列

java - ArrayList 通过引用传递日期对象?