无法使用 Blowfish ECB 将解密代码从 Java 转换为 Node.js
Cannot convert decryption code usingg Blowfish ECB from Java to Node.js
我似乎无法弄清楚是什么导致了语言之间的差异。在 Java 我有:
byte[] buf = Base64.getDecoder().decode("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t");
System.out.println(buf.length);
String key = "" + 2270457870L;
byte[] keyBytes = key.getBytes("UTF8");
System.out.println(keyBytes.length);
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "Blowfish"));
byte[] newBytes = cipher.doFinal(buf);
System.out.println(newBytes.length);
System.out.println(Arrays.toString(newBytes));
(可在 http://ideone.com/0dXuJL 在线运行)
然后在 Node 中我把它变成了:
const buf = Buffer.from("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t");
console.log(buf.length);
const keyBytes = Buffer.from('2270457870', 'utf8');
console.log(keyBytes.length);
const decipher = require('crypto').createDecipher('bf-ecb', keyBytes);
const buffers = [];
buffers.push(decipher.update(buf));
buffers.push(decipher.final());
const newBytes = Buffer.concat(buffers);
console.log(newBytes.length);
console.log(newBytes);
(可在 https://tonicdev.com/paulbgd/57b66c8ea0630d1400081ad0 在线运行)
输出错误:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
这里有几个问题:
buf
缺少字符串编码。默认情况下,使用 utf8
,但字符串实际上是 base64 编码的。要解决这个问题,请改用:
const buf = Buffer.from("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t", "base64");
传递给createDecipher()
的第二个参数是一个密码,不是一个键。不同之处在于 createDecipher()
对密码参数(使用 MD5)进行哈希处理以生成密钥。由于您已经拥有密钥,因此您需要的是 createDecipheriv()
,它需要密钥和 IV。 IV 参数可以只是一个零长度缓冲区,因为 ECB 模式不使用 IV。所以改用这个:
const decipher = require('crypto').createDecipheriv('bf-ecb', keyBytes, Buffer.alloc(0));
最后,如果你想匹配从Java输出的字节,你可以用这样的东西替换console.log(newBytes)
:
for (var i = 0; i < newBytes.length; ++i)
process.stdout.write(newBytes.readInt8(i) + ' ');
console.log();
我似乎无法弄清楚是什么导致了语言之间的差异。在 Java 我有:
byte[] buf = Base64.getDecoder().decode("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t");
System.out.println(buf.length);
String key = "" + 2270457870L;
byte[] keyBytes = key.getBytes("UTF8");
System.out.println(keyBytes.length);
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "Blowfish"));
byte[] newBytes = cipher.doFinal(buf);
System.out.println(newBytes.length);
System.out.println(Arrays.toString(newBytes));
(可在 http://ideone.com/0dXuJL 在线运行)
然后在 Node 中我把它变成了:
const buf = Buffer.from("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t");
console.log(buf.length);
const keyBytes = Buffer.from('2270457870', 'utf8');
console.log(keyBytes.length);
const decipher = require('crypto').createDecipher('bf-ecb', keyBytes);
const buffers = [];
buffers.push(decipher.update(buf));
buffers.push(decipher.final());
const newBytes = Buffer.concat(buffers);
console.log(newBytes.length);
console.log(newBytes);
(可在 https://tonicdev.com/paulbgd/57b66c8ea0630d1400081ad0 在线运行)
输出错误:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
这里有几个问题:
buf
缺少字符串编码。默认情况下,使用utf8
,但字符串实际上是 base64 编码的。要解决这个问题,请改用:const buf = Buffer.from("AutMdzthDvPlE+UnhcHa2h4UZGPdme7t", "base64");
传递给
createDecipher()
的第二个参数是一个密码,不是一个键。不同之处在于createDecipher()
对密码参数(使用 MD5)进行哈希处理以生成密钥。由于您已经拥有密钥,因此您需要的是createDecipheriv()
,它需要密钥和 IV。 IV 参数可以只是一个零长度缓冲区,因为 ECB 模式不使用 IV。所以改用这个:const decipher = require('crypto').createDecipheriv('bf-ecb', keyBytes, Buffer.alloc(0));
最后,如果你想匹配从Java输出的字节,你可以用这样的东西替换console.log(newBytes)
:
for (var i = 0; i < newBytes.length; ++i)
process.stdout.write(newBytes.readInt8(i) + ' ');
console.log();