背景:有效的方法
我们不时会使用一个读取PKCS#12密钥库的Java软件。对于这个特定项目,我们必须根据需要创建公共/私有对,并且我们将密钥存储在PKCS12文件中,因为它很稳定,几乎所有东西都可以读取该格式。
因为我们在内部做了很多Java,所以我们坐在keytool
,所以我们认为嘿,只需使用keytool来创建私钥和证书。典型的实例如下所示:
keytool -keystore MyLuggage.p12 -storepass 123456 -storetype pkcs12
-alias "......"
-genkeypair -keyalg RSA -keysize typically_2048_or_3072 -sigalg SHA256withRSA
-ext "KeyUsage=dataEncipherment,digitalSignature,keyEncipherment"
-startdate ....
-dname "......."
在实践中,实际-keysize
在2048到8192之间变化;出于这个问题的目的,似乎并没有使用什么,但显然我们使用适合任务的密钥长度,如果我们完全选择它们(通常由其他软件的约束决定,或由一些规定交给我们)。
这一直有效,因为其他软件 - 包括一开始提到的Java软件 - 可以读取密钥库并使用其中的私钥。 (并且可以导出和使用公钥等)。
这是什么打破
该软件最近升级到使用RSA的FIPS 140认证Java库的版本。 (“BSAFE”或“JSAFE”取决于你问的是谁。)现在,试图打开以前创建的PKCS#12文件失败
java.lang.SecurityException: Algorithm not allowable in FIPS140 mode: PBE/PKCS12/SHA1/RC2/CBC/40
at ......
at java.security.KeyStore.load(Unknown Source)
elided ......帧在我们没有的RSA源中,并且看起来使用在任何情况下都被混淆的函数名。因此,查看他们的来源以尝试找出导致这种情况的确切测试,不是一种选择。
那么, 导致了什么?我们选择的唯一算法是“RSA”密钥生成和“SHA256withRSA”签名,这两种算法都是FIPS 140-2允许的。我一直在查看keytool -genkeypair -help
输出,似乎没有任何其他算法或安全选项。 (我们避免使用-keypass
,因为当密钥库密码和密钥密码不同时,PKCS#12工具真的很讨厌它,而keytool -genkeypair
默认密钥密码是密钥库密码。)其余部分错误消息令人困惑,因为我们没有在任何地方指定使用SHA-1或RC2(!)。
搜索创建SSL证书时遇到问题的人,我们在这里没有这样做,而且给出的解决方案似乎特定于Tomcat。
这是我们如何创建密钥库的问题,我们如何在密钥库中创建密钥对,或者我们以前没有遇到的FIPS 140的某些“功能” ?
答案 0 :(得分:3)
PKCS#12存储使用密码派生密钥加密的私钥。它看起来像keytool使用pbeWithSHAAnd128BitRC2-CBC (pkcs-12PbeIds 5)
,这是一个PBES1算法。即使是Oracle Java 9的keytool.exe也可以使用此算法,因为您可以通过将.p12文件上传到online ASN.1 decoder decoding a sample PKCS#12 file进行验证。
如果我正确地阅读PKCS#12 standard PBES1很久以前就被#34;较新的"密钥派生系统的版本名为" PBES2"应该使用(主要是基于PBKDF2)而不是。但keytool没有使用它。这是我对错误信息的解释。
因此证书和密钥可以接受,但不接受PKCS#12容器。您可以尝试提取密钥和证书,并使用当前软件(如OpenSSL)将它们保存在新的PKCS#12文件中(或者您只需使用OpenSSL直接生成整个PKCS#12文件)。
OpenSSL可以选择指定用于密钥和证书加密的PBE(PKCS#12模式下的参数-keypbe
和-certpbe
)。我没有检查过,但像AES-256-CBC
这样的算法应该与FIPS140兼容。