使用AES/ECB/PKCS5Padding加密JSON对象报错,求解决方案
解决AES/ECB/PKCS5Padding加密JSON对象报错问题
原代码的核心问题
- JSON序列化方式错误:用
ObjectOutputStream序列化JSONObject会生成Java专属的对象字节流,而非标准JSON格式的字节,既不符合通用加密场景的预期,还可能引发序列化兼容性问题。 - 密钥长度不匹配:AES要求密钥长度必须为128/192/256位(对应16/24/32字节),如果你的
generateHash方法生成的哈希长度不符合这个要求,会直接抛出InvalidKeyException。 - 加密结果转字符串逻辑错误:加密后的二进制字节直接转字符串会出现乱码,必须用Base64编码为可打印的字符串格式。
修正后的完整代码
import org.json.JSONObject; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.Base64; public class PasswordUtils { public static String encryptJson(JSONObject inputParams) throws Exception { // 1. 将JSONObject转为标准JSON字符串,再转UTF-8字节数组 String jsonStr = inputParams.toString(); byte[] jsonBytes = jsonStr.getBytes(StandardCharsets.UTF_8); // 2. 生成符合AES要求的密钥(这里用SHA-256生成256位密钥) String key = "qPNNbUwcSOhXgWGwdBOXopjgSNPynDkC"; byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hashedKey = digest.digest(keyBytes); // 32字节(256位),符合AES-256要求 // 3. 初始化AES加密器 SecretKeySpec secretKeySpec = new SecretKeySpec(hashedKey, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); // 4. 加密并转Base64字符串 byte[] encryptedBytes = cipher.doFinal(jsonBytes); return Base64.getEncoder().encodeToString(encryptedBytes); } // 调用示例 public static void main(String[] args) throws Exception { JSONObject inputParams = new JSONObject(); inputParams.put("referenceid", "12345"); inputParams.put("sourcetype", "APP"); inputParams.put("source", "ANDROID"); String encryptedInput = PasswordUtils.encryptJson(inputParams); System.out.println("加密结果:" + encryptedInput); } }
额外注意事项
- 若环境不支持AES-256(需Java无限制权限文件),可改用128位密钥:
byte[] hashedKey = java.util.Arrays.copyOf(digest.digest(keyBytes), 16); - ECB模式安全性较低,业务允许的话建议改用CBC/GCM等模式(CBC需额外初始化向量IV,GCM支持认证加密)。
- 密钥不要硬编码在代码中,建议从配置文件或密钥管理服务读取。
内容的提问来源于stack exchange,提问作者bala subramanian
相关产品推荐
相关产品推荐

