OpenSSL 1.1.x迁移至3.1.1:p12转crt/key遇RC2-40-CBC不支持问题
问题场景
为Java Web应用(基于Apache Tomcat+Apache HTTPD代理)创建自签名证书,此前用OpenSSL 1.1.1配合keytool流程正常,迁移到OpenSSL 3.1.1后,执行PKCS12文件提取证书/密钥步骤时出现以下错误:
Error outputting keys and certificates
94210000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto\evp\evp_fetch.c:341:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()
原执行流程:
- 创建JKS密钥库
keytool -genkeypair -alias keystore -keyalg RSA -keystore C:\SSL\PVIStore -keysize 2048
- 转换为PKCS12格式
keytool -importkeystore -srckeystore C:\SSL\PVIStore -destkeystore C:\SSL\PVIStore.p12 -deststoretype PKCS12
- 提取证书
openssl pkcs12 -in C:\PVIStore.p12 -nokeys -out C:\SSL\PVIStore.crt
- 提取密钥
openssl pkcs12 -in C:\PVIStore.p12 -nocerts -nodes -out C:\SSL\PVIStore.key
问题原因
OpenSSL 3.0及以上版本默认禁用了RC2-40-CBC这类弱加密算法,而旧版keytool在将JKS转换为PKCS12时,默认使用RC2-40-CBC加密证书条目,导致OpenSSL 3.1.1无法解析。
无legacy开关的解决方案
方案1:转换PKCS12时指定强加密算法
从Java 8u301及以上版本开始,keytool支持通过JVM参数指定PKCS12的加密算法,避免使用RC2。修改转换命令如下:
keytool -importkeystore -srckeystore C:\SSL\PVIStore -destkeystore C:\SSL\PVIStore.p12 -deststoretype PKCS12 -deststorepass <你的存储密码> -destkeypass <你的密钥密码> -J-Dkeystore.pkcs12.encryptCertificates=true -J-Dkeystore.pkcs12.certEncryptionAlgorithm=AES_256_CBC -J-Dkeystore.pkcs12.keyEncryptionAlgorithm=AES_256_CBC
参数说明:
-J-Dkeystore.pkcs12.encryptCertificates=true:启用证书条目加密-J-Dkeystore.pkcs12.certEncryptionAlgorithm=AES_256_CBC:指定证书用AES-256-CBC加密-J-Dkeystore.pkcs12.keyEncryptionAlgorithm=AES_256_CBC:指定密钥用AES-256-CBC加密
方案2:直接生成PKCS12格式密钥库
跳过JKS转PKCS12的步骤,直接用keytool生成PKCS12格式的密钥库,同时指定强加密算法:
keytool -genkeypair -alias keystore -keyalg RSA -keystore C:\SSL\PVIStore.p12 -storetype PKCS12 -keysize 2048 -storepass <你的存储密码> -keypass <你的密钥密码> -J-Dkeystore.pkcs12.encryptCertificates=true -J-Dkeystore.pkcs12.certEncryptionAlgorithm=AES_256_CBC
验证
用新生成的PVIStore.p12执行原步骤3、4的OpenSSL命令,即可正常提取.crt和.key文件,不会再出现RC2相关错误。
内容的提问来源于stack exchange,提问作者Sharda Prasad Jaiswal

