使用not-yet-commons-ssl实现指定OpenSSL AES-256-CBC加密遇解密错误
实现与指定OpenSSL命令等效的AES-256-CBC加密(not-yet-commons-ssl)
你需要对齐的OpenSSL命令为:
openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in geometry.json -out geometry.json.enc -pass pass:"password"
使用not-yet-commons-ssl:0.3.13默认参数加密后出现bad decrypt错误,核心原因是默认参数与OpenSSL的密钥派生、盐处理逻辑不匹配。以下是必须配置的参数及实现要点:
核心参数配置
必须确保以下参数与OpenSSL命令完全对齐:
- 加密算法:指定为
AES/CBC/PKCS5Padding(OpenSSL默认使用PKCS#7填充,与PKCS5Padding在块密码场景下等价) - 盐处理:启用加盐模式,按OpenSSL标准生成8字节随机盐,并在输出文件开头写入
Salted__标识+盐值 - 密钥派生函数:指定为PBKDF2,对应OpenSSL的
-pbkdf2选项 - PBKDF2迭代次数:设置为
10000,对应-iter 10000 - 密钥长度:AES-256需32字节密钥,CBC模式IV长度固定为16字节
- 密码:直接使用指定的明文密码,无需额外预处理
Java代码示例(基于not-yet-commons-ssl)
import org.apache.commons.ssl.PasswordBasedEncryptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.SecureRandom; public class OpenSSLEquivalentEncryption { public static void main(String[] args) throws Exception { String password = "password"; String inputPath = "geometry.json"; String outputPath = "geometry.json.enc"; // 初始化加密器并配置核心参数 PasswordBasedEncryptor encryptor = new PasswordBasedEncryptor(); encryptor.setAlgorithm("AES/CBC/PKCS5Padding"); encryptor.setKeyDerivationFunction(PasswordBasedEncryptor.PBKDF2); encryptor.setIterations(10000); encryptor.setKeySize(256); // 生成OpenSSL标准的8字节随机盐 byte[] salt = new byte[8]; new SecureRandom().nextBytes(salt); // 写入OpenSSL格式的盐头,再加密写入数据 try (FileOutputStream out = new FileOutputStream(outputPath)) { out.write("Salted__".getBytes()); out.write(salt); encryptor.setSalt(salt); encryptor.encrypt(new FileInputStream(inputPath), out, password.toCharArray()); } } }
关键说明
- 盐头写入:OpenSSL的
-salt选项会自动在加密文件开头添加Salted__标识+8字节盐值,代码必须手动完成这一步,否则OpenSSL解密时无法识别盐,导致密钥生成错误。 - 填充匹配:必须指定
PKCS5Padding填充方式,否则解密时会出现填充不匹配的bad decrypt错误。 - 迭代次数强制设置:not-yet-commons-ssl的PBKDF2默认迭代次数可能与OpenSSL的10000不一致,必须显式指定。
内容的提问来源于stack exchange,提问作者Prashanth Kumar B
相关产品推荐
相关产品推荐

