2

I'm trying to replicate a Java-based encryption scheme in Node.js but unfortunately I'm getting inconsistent results.

Here's the Java method:

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;
}

And my Node version:

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');
};

When I pass both functions the string "SomeJSON" and the same key I get different encrypted results.

From Java: ENnQzWowzrl7LQchRmL7sA== From Node: TGreJNmQH92gHb1bSy4xAA==

I can't figure out what is different in my Node implementation.

4

1 回答 1

1

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

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

或者

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

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

于 2015-06-23T20:58:15.787 回答