【安全贴士】PKCS12弱加密算法分析
在CentOS7和JDK8中,默认使用的openssl或keytool命令生成的PKCS12证书库,
使用的加密算法为弱加密算法pbeWithSHA1And40BitRC2-CBC
,需要升级为新的安全算法。
可通过如下命令查看PKCS12格式的证书库文件详细信息。
1 | [root@mail CA]# openssl pkcs12 -info -in root78.p12 -nodes |
升级方案
openssl命令可以通过参数来指定加密算法
1 | # 导出包含CA链的PKCS12格式证书库 |
JDK8目前并不能解析这种加密方式的证书库,因此需要添加开源库bouncycastle
,Java中加载证书库的时候指定provider为BC
才能解析。
方法是在代码中添加Security.addProvider(new BouncyCastleProvider())
。
或者更好的做法是在jre的java.security
文件中添加
1 | security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider |
另外如果在Tomcat配置HTTPS双向认证,则同样需要指定证书库和信任证书库的provider为BC
。
JDK版本问题
按照上面做法做之后,仍然无法解决问题。使用这种方式导出来的server.p12
证书库是没有问题的,但是如果使用这种方式导出信任证书root.p12
,则无法使用。 经过反复测试后发现,由于root.p12
缺少别名导致,而openssl无法对每个证书单独设置别名。事实上,openssl对于信任证书库的支持很有限。 因此无法通过openssl命令来生成、导入、导出、删除信任证书库等操作,只能通过keytool命令。
对于keytool命令,需要使用高版本的JDK来导出信任证书库,具体参考:https://bugs.openjdk.java.net/browse/JDK-8228481。 根据bug说明,对于JDK8、11、15、16、17都解决了,但是实测发现8和11都不行,只有OpenJDK 15支持。主要是这个补丁版还没发布吧。 等后续再看看是否已修复。
方法就是下载OpenJDK 15之后,修改jre中的java.security
1 | keystore.pkcs12.certProtectionAlgorithm=PBEWithHmacSHA256AndAES_256 |
然后使用OpenJDK 15的keytool工具生成信任证书库root.p12
。
1 | keytool -import -noprompt -trustcacerts -alias caroot -file root.crt -keystore root.p12 -storetype PKCS12 |
也就是说证书server.p12
由openssl
命令生成,而信任证书库root.p12
由keytool
工具生成。 生成之后对于证书的解析方法仍然是需要使用BC
。