java - NodeJs 从 JAVA 解密 AES256 加密
问题描述
我正在与另一个系统集成,给定的数据在 AES-256-CBC(Java) 中加密,需要在 NodeJs 中对其进行解密才能继续。
我从互联网上尝试了很多方法并陷入了错误。以下是正在运行的 Java(解密)和 NodeJs(我的解密代码)的示例代码
private static final int ITERATION_COUNT = 65536;
private static final int KEY_LENGTH = 256;
private static final byte[] DEFAULT_IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public static byte[] decryptToBytes(String src, String secret, String salt, byte[] iv) {
try{
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secret.toCharArray(), salt.getBytes(), ITERATION_COUNT, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
return cipher.doFinal(Base64.getDecoder().decode(src));
}catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String src, String secret, String salt, byte[] iv) {
try{
return new String(decryptToBytes(src, secret, salt, iv));
}catch (Exception ex) {
return null;
}
}
public static void main(String[] args) {
String secret = "abcd123456";
String salt = "123abc";
String plainText ="This is AES256 encryption test";
String cipherText = "gbYgtu5EWxOYRSUmMsEtdn8oQLxBjejfwUBSRhhls08=";
byte[] IV = new byte[16];
String originalText = decrypt(cipherText,secret, salt, IV);
}
import crypto from "crypto";
public aesCdcDecrypt(input: string) {
let iterationCount = 65536;
let keyLength = 256;
let iv = new Buffer(16);
let keyHex = "abcd123456";
let salt = "123abc";
let decryptText: string;
try {
crypto.pbkdf2(new Buffer(keyHex), new Buffer(salt), iterationCount, keyLength, "sha256", function (err, key) {
let secretKey = key.toString("hex");
let decipher = crypto.createDecipheriv("aes-256-cbc", secretKey, iv);
decryptText = decipher.update(input, "binary", "utf8");
decryptText += decipher.final("utf8");
console.log('Result: ' + decryptText);
});
} catch (e) {
console.log(e);
}
return decryptText;
}
结果出现此错误 --> 错误:Object.createDecipheriv (crypto.js:627:10) 处的新 Decipheriv (crypto.js:267:16) 处的密钥长度无效
解决方案
您的 TS 代码中有一些小问题:
key
长度以字节为单位,而不是位new Buffer()
默认情况下不解码 base64
这是一个工作版本(JS):
const crypto = require('crypto')
function aesCdcDecrypt(ciphertext) {
let iterationCount = 65536;
let keyLength = 32;
let iv = Buffer.alloc(16);
let keyHex = "abcd123456";
let salt = "123abc";
let key = crypto.pbkdf2Sync(keyHex, Buffer.from(salt), iterationCount, keyLength, "sha256");
var cipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
cipher.setAutoPadding(true);
let ciph = cipher.update(Buffer.from(ciphertext, "base64"));
let ciphf = cipher.final();
return Buffer.concat([ciph, ciphf]).toString();
}
console.log(aesCdcDecrypt("gbYgtu5EWxOYRSUmMsEtdn8oQLxBjejfwUBSRhhls08="));
印刷:
This is AES256 encryption test
推荐阅读
- c++ - 是否可以在 C++ 中基于给定标识符创建基类的新实例,反之亦然
- javascript - 根据矩阵B的排序对矩阵A进行排序
- javascript - 有没有办法在查询构建器的“with”子句中添加计数?
- three.js - 在组件内部的Aframe中导入threejs代码
- php - Laravel 发送带有降价的电子邮件不记录
- mysql - 使用 Inner Join/Group_Concat 更新两个表之间的 Inner Join 返回子查询错误
- angular - 无法在角度中设置未定义的属性?
- c++ - 如何在 Xcode 中定义 DOBJC_OLD_DISPATCH_PROTOTYPES?
- kubernetes - Kubernetes:为 Kafka 创建一个入口
- sql - 在非唯一列中生成唯一 ID