You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Java中模拟Node.js crypto.createCipher的AES-128-ECB代码改为AES-256-ECB?

解决AES-256-ECB适配Node.js crypto.createCipher的Java实现问题

原代码的核心问题是:AES-256需要32字节(256位)密钥,但你当前只通过一次MD5哈希生成了16字节密钥,且SecretKeySpec的第二个参数传入了完整的模式填充字符串(正确应该只传算法名"AES")。另外Node.js的crypto.createCipher使用OpenSSL的EVP_BytesToKey算法派生密钥,不是简单补零,需要匹配这个逻辑。

修改后的完整代码

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;

// 假设ENCRYPTION_KEY是你的密码字符串
String ENCRYPTION_KEY = "your-password-here";
byte[] input = jo.toString().getBytes("utf-8");

MessageDigest md = MessageDigest.getInstance("MD5");
byte[] passwordBytes = ENCRYPTION_KEY.getBytes("UTF-8");

// 按照EVP_BytesToKey生成32字节AES-256密钥
byte[] keyBytes = new byte[32];
byte[] digest = md.digest(passwordBytes);
// 第一次哈希结果填充前16字节
System.arraycopy(digest, 0, keyBytes, 0, 16);
// 第二次哈希:用第一次的digest + 原密码字节做哈希,填充后16字节
md.update(digest);
md.update(passwordBytes);
digest = md.digest();
System.arraycopy(digest, 0, keyBytes, 16, 16);

// SecretKeySpec的第二个参数仅需指定算法"AES"
SecretKeySpec skc = new SecretKeySpec(keyBytes, "AES");
// 初始化AES-256-ECB加密器,填充方式和Node.js一致
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);

byte[] cipherText = cipher.doFinal(input);
String query = Base64.getEncoder().encodeToString(cipherText);

关键修改点说明

  • 密钥生成逻辑:严格匹配Node.js crypto.createCipher的EVP_BytesToKey流程,通过两次MD5哈希拼接出32字节密钥(第一次哈希密码,第二次哈希「第一次哈希结果+原密码」)
  • SecretKeySpec参数修正:第二个参数应为算法名"AES",而非包含模式和填充的字符串,避免密钥解析错误
  • 简化加密流程:直接使用cipher.doFinal(input)替代update+doFinal的分步写法,结果一致但更简洁
  • Base64编码:改用Java标准库的Base64.getEncoder(),和Android的Base64.DEFAULT行为一致(默认换行,若需无换行可替换为Base64.NO_WRAP,需和Node端保持一致)

内容的提问来源于stack exchange,提问作者Priya Baweja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:07:46