密钥库类型:使用哪个?


114

通过查看java.securitymy 的文件JRE,我发现默认使用的密钥库类型设置为JKS在这里,列出了可以使用的密钥库类型。

有推荐的密钥库类型吗?不同密钥库类型的优缺点是什么?


4
从Java 9开始,PKCS12是默认的密钥库类型。这项更改是针对JEP 229目标的:“提高了安全性。PKCS12提供了比JKS更强大的加密算法。” 有关更多信息,请参见“ JEP 229:默认情况下创建PKCS12密钥库”,openjdk.java.net/jeps/229 ; 上次访问时间为2018
。– buzz3791

Answers:


141

除了链接到的标准名称列表中列出的类型以外,还有更多类型。您可以在加密提供程序文档中找到更多信息。当然,最常见的是JKS(默认)和PKCS12(对于PKCS#12文件,通常带有扩展名.p12,有时带有.pfx)。

如果您停留在Java世界中,那么JKS是最常见的。PKCS#12不是特定于Java的,使用从浏览器或基于OpenSSL的工具备份的证书(带有私钥)特别方便(keytool在Java 6之前无法转换密钥库并导入其私钥) ,因此您必须使用其他工具)。

如果您已经拥有PKCS#12文件,则PKCS12直接使用该类型通常会更容易。可以转换格式,但是如果直接选择密钥库类型,则几乎没有必要。

在Java 7中,PKCS12它主要用作密钥库,但对于信任则用处不大(请参阅密钥库和信任库之间区别),因为没有私有密钥就无法存储证书条目。相反,JKS不需要每个条目都是私钥条目,因此您可以拥有仅包含证书的条目,这对于信任存储非常有用,在信任存储中,您存储了信任的证书列表(但是您没有他们的私钥)。

Java 8中对此进行了更改,因此您现在也可以在PKCS12商店中使用仅证书条目。(有关这些更改和更多计划的更多详细信息,请参见JEP 229:默认情况下创建PKCS12密钥库。)

还有其他一些密钥库类型,可能使用频率较低(取决于上下文),这些类型包括:

  • PKCS11,用于PKCS#11库,通常用于访问硬件加密令牌,但是Sun提供程序实现也通过此方法支持NSS存储(来自Mozilla)。
  • BKS,使用BouncyCastle提供程序(通常用于Android)。
  • Windows-MY/ Windows-ROOT,如果要直接访问Windows证书存储区。
  • KeychainStore,如果您想直接使用OSX钥匙串。

7
@ husayt,PEM证书不直接作为密钥库类型支持(我想可以KeyStore为此写一个实现)。但是,您可以使用来将它们动态地加载到内存中的密钥库实例(通常是JKS,默认类型)中CertificateFactory如此答案所示)。
布鲁诺2014年

我认为JKS已改为JCEKS
两栖游戏,2014年

5
更重要的是,JKS密钥存储区无法存储秘密密钥。对于此用例,JCEKS是合适的。您的答案中可能值得一提。
Duncan Jones

1
好。在Java 8中,我可以使用单个证书创建PKCS#12密钥库,而不会出现任何问题。请注意,对于P12,证书条目是隐式信任的。如果您需要不受信任的证书,则可能必须恢复为具有多个密钥存储区的方案。
Maarten Bodewes,2016年

2
至少对于Java 8 PKCS#12密钥库还可以,但是仍然不能存储秘密密钥条目。存储此类密钥存储库(ugh)时,您将得到一个空指针异常,这可能是因为它找不到关联的证书。似乎有人跳过了约书亚关于快速失败代码的教义。
Maarten Bodewes,2016年

21

这是一篇介绍Java中不同类型的密钥库以及不同类型的密钥库之间的区别的文章。http://www.pixelstech.net/article/1408345768-Different-types-of-keystore-in-Java----概述

以下是该帖子中不同密钥库的描述:

JKS,Java密钥库。您可以在sun.security.provider.JavaKeyStore中找到此文件。该密钥库特定于Java,通常具有jks的扩展名。这种类型的密钥库可以包含私钥和证书,但不能用于存储秘密密钥。由于它是Java特定的密钥库,因此不能在其他编程语言中使用。

JCEKS,JCE密钥库。您可以在com.sun.crypto.provider.JceKeyStore中找到此文件。该密钥库的扩展名为jceks。可以放入JCEKS密钥库中的条目是私钥,秘密密钥和证书。

PKCS12,这是一种标准的密钥库类型,可以在Java和其他语言中使用。您可以在sun.security.pkcs12.PKCS12KeyStore中找到此密钥库实现。它通常具有p12或pfx的扩展名。您可以存储这种类型的私钥,私钥和证书。

PKCS11,这是硬件密钥库类型。它为Java库提供一个接口,以与硬件密钥库设备(例如Luna,nCipher)连接。您可以在sun.security.pkcs11.P11KeyStore中找到此实现。加载密钥库时,无需创建具有特定配置的特定提供程序。该密钥库可以存储私钥,秘密密钥和证书。加载密钥库时,将从密钥库中检索条目,然后将其转换为软件条目。


@ peci1我计划编写一些有关如何使用这些密钥库的教程。到目前为止,我已经为JKS撰写了一篇文章,请在pixeltech.net/article/…上
PixelsTech

@PixelsTech我已经找到了这个,并且想知道它们的其余部分:)所以我会继续关注;)谢谢
Martin Pecka 2015年

1
@ peci1我今天讨论了JCEKS和PKCS12。对于PKCS11,它涉及硬件和额外的配置,需要更多的时间来编写它。pixelstech.net/article/…pixelstech.net/article/…–
PixelsTech

哇,那是闪电般的速度!非常感谢。
马丁·佩卡

4

如果您使用的是Java 8或更高版本,则一定要选择PKCS12,这是Java 9(JEP 229)以来的默认设置。

JKS和相比的优势JCEKS是:

  • 可以存储秘密密钥,私钥和证书
  • PKCS12是一种标准格式,可以被其他程序和库读取1
  • 改进的安全性:JKS并且JCEKS非常不安全。可以通过暴力破解这些密钥库类型的密码的工具的数量来看出这一点,在Android开发人员中尤其如此。2 3

1JDK-8202837,已在Java 11中修复。

2所有密钥库类型(包括PKCS12)使用的PBE的迭代计数过去通常都是一周(CVE-2017-10356),但是在9.0.1、8u151、7u161和6u171中已解决此问题。

3要进一步阅读:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.