crypto.pbkdf2(node.js)和PBEKeySpec之间密钥长度的差异

时间:2013-12-02 16:04:07

标签: java node.js encryption interop

我正在研究一些可互操作的代码,用于加密/解密Java和node.js之间的字符串,并设法让node.js解密Java加密的内容,这是成功解密的最后一部分:密钥。

要在Java中派生密钥,我们写:

private static Key deriveSecretKey(String secretKeyAlgorithm, String secretKey, String salt) throws Exception {

  SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_ALGORITHM);
  KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), char2byte(salt), 65536, 128);
  SecretKey tmp = factory.generateSecret(spec);
  SecretKey secret = new SecretKeySpec(tmp.getEncoded(), secretKeyAlgorithm);

  return secret;
}

请注意,传递给PBEKeySpec()的密钥长度为128。但是,在node.js中,如果我尝试使用128并且实际上必须在此处使用16,则会得到“无效密钥长度”:

crypto.pbkdf2(key_value, salt_value, 65536, 16, function(err, key) {
   var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);

   // decipher.setAutoPadding(false);
   var decoded = decipher.update(ciphertext, 'binary', 'utf8');
   decoded += decipher.final('utf8');

   console.log('Result: ' + decoded);
});

控制台输出:

结果:超级秘密 - 就在这里。

很好奇为什么在指定这两个函数之间的密钥长度时存在差异。谢谢!

1 个答案:

答案 0 :(得分:0)

通常,密钥大小以位为单位定义。但是,大多数加密库都不能处理不能被8分割的位大小 - 输出几乎总是以八位字节(8位字节)为单位。因此,如果用户必须指定位的大小,或八位字符串(字节数组)中的八位字节数,则由API的设计者决定。

真正了解为什么选择位或字节的唯一方法是询问设计库的人。在我自己的代码中,我确实尝试遵循(ad-hoc)标准 - 所以对于密钥大小的位。如果从上下文中不清楚哪个,最好使用blockSizeBitsblockSizeBytes之类的名称。当然,文档也可能有所帮助,但在我看来,使用特定标识符是最好的。