【问题标题】:keytool versus FIPS when handling PKCS12 keystores处理 PKCS12 密钥库时的 keytool 与 FIPS
【发布时间】:2018-10-24 10:34:13
【问题描述】:

背景:有效的方法

有时我们不得不使用一个读取 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)

省略的......帧位于我们没有的 RSA 源代码中,并且看起来使用在任何情况下都被混淆的函数名称。因此,查看他们的来源以尝试找出究竟是什么测试导致了这种情况,这不是一种选择。

那么, 是什么原因造成的呢?我们选择的唯一算法是“RSA”密钥生成和“SHA256withRSA”签名,这两种算法都是 FIPS 140-2 允许的。我一直在查看keytool -genkeypair -help 输出,似乎没有任何其他算法或安全选项。 (我们避免使用-keypass,因为PKCS#12 工具非常讨厌密钥库密码和密钥密码不同时使用它,而keytool -genkeypair 将密钥密码默认为密钥库密码。)其余的错误消息令人困惑,因为我们没有在任何地方指定使用 SHA-1 或 RC2 (!)。

谷歌搜索发现人们在创建 SSL 证书时遇到问题,我们在这里没有这样做,并且给出的解决方案似乎特定于 Tomcat。

这是我们如何创建密钥库的问题,我们如何在密钥库中创建密钥对,或者我们以前没有遇到过的 FIPS 140 的某些“功能” ?

【问题讨论】:

  • 使用其他应用程序(可能是 OpenSSL 或 Windows Crypto 库?)创建 PKCS12 文件是否可以与您需要互操作的软件一起使用?软件提供商是否有推荐的或记录在案的工具来创建与其一起使用的 PKCS12 文件?
  • 如果 BSAFE-Java 是提供者的形式,我期望,你可以通过指定 -providername-providerclass 来使用它来创建密钥库,它应该这样做所以使用算法它将能够回读。
  • @dave_thompson_085 BSAFE 提供程序类在磁盘上不可用,这是 -provider* 选项所要求的。我们最终将不得不自己编写 PKCS#12 文件,并将 SunJSSE 和 BC 的使用限制为仅处理内存中的对象而不是磁盘存储。除非 BC API 允许控制 certbag 算法……那将是明天的调查!
  • 您是指 BSAFE (RSA/EMC/Dell) 还是 BC (BouncyCastle)?那些是完全不同的。如果您可以使用 BC 提供程序,它的密钥库类型为 PKCS12-3DES-3DESPKCS12-DEF-3DES-3DES,这对于 FIPS 来说应该没问题(尽管我无法测试)。如果您想使用 BC 自己的 API,即 LWAPI,请参阅superuser.com/questions/1102971/… 了解起点。
  • 对。 BSAFE 提供程序不在磁盘上,因此我们无法将其用途指定为keytool。我正在使用部分 BC 提供程序,但正如您在下面指出的那样,它仍然默认为 40 位 RC2 certbag。我明天的计划(好吧,今天,喝杯咖啡后)是调查也使用 BC 提供程序来处理 PKCS#12 文件,并指定不太愚蠢的 3DES 算法。 (编辑:是的,你的链接说的,那部分!)

标签: java keytool pkcs#12 fips


【解决方案1】:

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 早就被名为“PBES2”(主要基于 PBKDF2)的“更新”版本的密钥派生系统取代,应该改用它。但是 keytool 没有使用它。这是我对错误信息的解释。

因此证书和密钥可能是可接受的,但 PKCS#12 容器是不可接受的。您可以尝试使用 OpenSSL 等当前软件提取密钥和证书并将它们保存在新的 PKCS#12 文件中(或者直接使用 OpenSSL 生成整个 PKCS#12 文件)。

OpenSSL 可以选择指定用于密钥和证书加密的 PBE(参数 -keypbe-certpbe 在 PKCS#12 模式下)。我还没有检查过,但是像AES-256-CBC 这样的算法应该是 FIPS140 兼容的。

【讨论】:

  • 实际上,如您的示例所示,SunJSSE(以及 BC、Windows 和 NSS 以及 OpenSSL 默认情况下)中 PKCS12 的 Java 实现使用 1.2.840.113549.1.12.1.3 加密密钥包pbeWithSHAAnd3-KeyTripleDES-CBC 和 certbag 与 1.2.840.113549.1.12.1.6 pbeWithSHAAnd40BitRC2-CBC;两者都在 PKCS12 附录 C 中定义——即使您说 PKCS12 已更新为更喜欢 PKCS5v2 PBES2。 3DES 已获得 FIPS 批准(尽管现在 首选 AES)但 RC2 不是——而且 PKCS12 PBE 的质量并不重要,因为 RC2-40 是故意较弱的。 ...
  • ...我一直不明白为什么在根本不需要加密 certbag 时,每个人都非常弱地加密它,但他们确实这样做了。 OpenSSL 可以使用-certpbe none 使其未加密,但我见过的其他软件都没有此选项。
猜你喜欢
  • 2018-03-29
  • 2015-09-22
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2021-08-03
  • 2021-08-18
  • 2012-12-31
相关资源
最近更新 更多