【发布时间】:2013-11-10 23:58:05
【问题描述】:
我有一个 Java 加密代码。我正在尝试将加密部分移植到节点。基本上,node 会使用 crypto 模块进行加密,然后 Java 会进行解密。
这是我在 Java 中进行加密的方法:
protected static String encrypt(String plaintext) {
final byte[] KEY = {
0x6d, 0x79, 0x56, 0x65, 0x72, 0x79, 0x54, 0x6f, 0x70,
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b
};
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(KEY, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final String encryptedString = Base64.encodeToString(
cipher.doFinal(plaintext.getBytes()), Base64.DEFAULT);
return encryptedString;
} catch (Exception e) {
return null;
}
}
这是我在节点中进行加密的方法:
var crypto = require('crypto'),
key = new Buffer('6d7956657279546f705365637265744b', 'hex'),
cipher = crypto.createCipher('aes-128-ecb', key),
chunks = [];
cipher.setAutoPadding(true);
chunks.push(cipher.update(
new Buffer(JSON.stringify({someKey: "someValue"}), 'utf8'),
null, 'base64'));
chunks.push(cipher.final('base64'));
var encryptedString = chunks.join('');
在 Java 中,我得到字符串 T4RlJo5ENV8h1uvmOHzz1KjyXzBoBuqVLSTHsPppljA=。这得到正确解密。但是,在节点中,我得到al084hEpTK7gOYGQRSGxF+WWKvNYhT4SC7MukrzHieM=,这显然是不同的,因此它不会被正确解密。
我试图寻找和我有同样问题的人,this github issue 是我能找到的最接近的问题。正如该问题中所建议的,我尝试像这样运行 openssl:
$ echo -e '{"someKey": "someValue"}' | openssl enc -a -e -aes-128-ecb -K "6d7956657279546f705365637265744b"
T4RlJo5ENV8h1uvmOHzz1MY2bhoFRHZ+ClxsV24l2BU=
我得到的结果和java产生的结果很接近,但还是不一样:
T4RlJo5ENV8h1uvmOHzz1MY2bhoFRHZ+ClxsV24l2BU= // openssl
T4RlJo5ENV8h1uvmOHzz1KjyXzBoBuqVLSTHsPppljA= // java
al084hEpTK7gOYGQRSGxF+WWKvNYhT4SC7MukrzHieM= // node
这让我想到了一个问题,如何让节点输出与我的 java 代码相同的加密字符串?我只能在 node 中更改我的代码,而不能在 java 中更改。
【问题讨论】:
-
每个使用什么填充格式?你怎么知道被加密的内容在每个平台上实际上是相同的(我认为没有理由假设 Node 的
JSON.stringify输出与你作为plaintext传递给 Java 的任何内容相同)? -
Java 正在使用 PKCS5Padding。从我读过的内容来看,openssl 也使用相同的(抱歉我丢失了链接)。对于节点,我不确定如何指定填充,这就是我选择使用
cipher.setAutoPadding(true)的原因。编辑:找到链接。查看接受的答案here -
两个输入是相同的。当我再次对此进行测试时,我将
JSON.stringify的输出(手动)传递给 javaencrypt,并带有一些转义字符:encrypt("{\"someKey\":\"someValue\"}") -
你需要比较字节数组。相同外观的文本可以用不同字符集的不同字节编码,
String#getBytes显式依赖于平台字符集。转储字节数组。 -
没有包含数组,java 转储看起来像这样:
7b22736f6d654b6579223a22736f6d6556616c7565227d这与它在 node.js 中的样子相同。可能问题出在其他地方。
标签: java node.js encryption openssl aes