如何解决OpenSSL AES加密与Java解密不兼容问题?
解决OpenSSL AES-ECB加密与Java解密不兼容的问题
问题根源
你遇到的填充异常和加密结果不一致,核心原因是密钥处理方式错误:
- OpenSSL的
-K参数接收的是十六进制字符串格式的密钥 - 但你在Java代码中错误地将该十六进制字符串当作Base64进行解码,导致两端实际使用的密钥完全不匹配,最终引发解密填充异常
至于ECB模式、无盐配置、填充方式(Java的PKCS5Padding与OpenSSL默认的PKCS#7填充在AES 16字节块大小下行为一致)都是匹配的,问题不在这些环节。
修正后的Java代码
下面是修正密钥处理逻辑后的代码,同时补充了十六进制转字节数组的工具方法,确保和OpenSSL使用相同密钥:
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class AESHandler { public static void main(String[] args) throws Exception { // OpenSSL使用的十六进制密钥字符串 String aesKeyHex = "BDC17ABE1F194C8DD49840C57A155013"; // 将十六进制字符串转换为字节数组(替代原Base64解码逻辑) byte[] keyBytes = hexToByteArray(aesKeyHex); SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 加密测试:验证与OpenSSL结果一致 cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] cipherText = cipher.doFinal("password".getBytes(StandardCharsets.UTF_8)); String encodedPassword = Base64.getEncoder().encodeToString(cipherText); System.out.println("加密结果(与OpenSSL匹配): " + encodedPassword); // 输出b3JCq/QmtKSmkQABYdbiVA== // 解密OpenSSL生成的密文 cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode("b3JCq/QmtKSmkQABYdbiVA==")); System.out.println("解密结果: " + new String(decryptedBytes, StandardCharsets.UTF_8)); // 输出password } // 十六进制字符串转字节数组工具方法 private static byte[] hexToByteArray(String hexStr) { int len = hexStr.length(); byte[] result = new byte[len / 2]; for (int i = 0; i < len; i += 2) { result[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4) + Character.digit(hexStr.charAt(i + 1), 16)); } return result; } }
额外验证提示
确保OpenSSL加密时的明文无多余换行符:
如果之前用文件加密,建议直接用管道命令避免文件换行干扰:
echo -n "password" | openssl enc -nosalt -aes-128-ecb -base64 -K BDC17ABE1F194C8DD49840C57A155013
该命令输出的密文会和Java代码加密结果完全一致。
内容的提问来源于stack exchange,提问作者fudriyak
相关产品推荐
相关产品推荐

