如何将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
相关产品推荐
相关产品推荐

