密钥库类型:使用哪一种?

Posted

技术标签:

【中文标题】密钥库类型:使用哪一种?【英文标题】:Keystore type: which one to use? 【发布时间】:2012-07-17 05:18:53 【问题描述】:

通过查看我的JRE 的文件java.security,我看到默认使用的密钥库类型设置为JKS。 Here,有一个可以使用的密钥库类型列表。

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

【问题讨论】:

从 Java 9 开始,PKCS12 是默认的密钥库类型。此更改是针对 JEP 229 的目标:“提高安全性。PKCS12 提供比 JKS 更强大的加密算法。”有关更多信息,请参阅“JEP 229:默认创建 PKCS12 密钥库”,openjdk.java.net/jeps/229;最后访问时间为 2018 年 2 月 2 日。 【参考方案1】:

Java 11 提供以下类型的KeyStores:

jceks:SunJCE 提供者提供的专有密钥库实现。

jks:SUN 提供者提供的专有密钥库实现。

dks:域密钥库是密钥库的集合,呈现为单个逻辑密钥库。它由配置数据指定,其语法在 DomainLoadStoreParameter 类中描述。

pkcs11:由 PKCS #11 令牌支持的密钥库。

pkcs12:PKCS #12 中定义的个人身份信息传输语法。

来源:https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#keystore-types

【讨论】:

【参考方案2】:

如果您使用的是 Java 8 或更新版本,则绝对应该选择 PKCS12,这是自 Java 9 以来的默认设置 (JEP 229)。

JKSJCEKS 相比的优势是:

可以存储密钥、私钥和证书 PKCS12是标准格式,可以被其他程序和库读取1 改进的安全性:JKSJCEKS 非常不安全。从这些密钥库类型的暴力破解密码工具的数量可以看出这一点,在 android 开发人员中尤其流行。2, 3

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

2 过去,所有密钥库类型(包括 PKCS12)使用的 PBE 的迭代次数都比较弱(CVE-2017-10356),但在 9.0.1、8u151、7u161、和 6u171

3 进一步阅读:

Mind Your Keys? A Security Evaluation of Java Keystores (PDF) Java KeyStores – the gory details

【讨论】:

【参考方案3】:

这里有一篇文章介绍了Java中不同类型的keystore以及不同类型的keystore之间的区别。 http://www.pixelstech.net/article/1408345768-Different-types-of-keystore-in-Java----Overview

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

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

JCEKS,JCE 密钥库。您可以在以下位置找到此文件 com.sun.crypto.provider.JceKeyStore。此密钥库的扩展名为 杰西克斯。可以放入 JCEKS 密钥库的条目是私有的 密钥、密钥和证书。

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

PKCS11,这是一种硬件密钥库类型。它为一个接口提供服务 用于连接硬件密钥库设备的 Java 库,例如 露娜,nCipher。您可以在以下位置找到此实现 sun.security.pkcs11.P11KeyStore。当您加载密钥库时,您没有 需要创建具有特定配置的特定提供程序。这 keystore 可以存储私钥、密钥和证书。什么时候 加载密钥库,将从密钥库中检索条目 然后转换成软件条目。

【讨论】:

@peci1 我计划写一些关于如何使用这些密钥库的教程。到目前为止,我已经为 JKS 写了一篇文章,请在 pixelstech.net/article/… 找到它 @PixelsTech 我找到了这个,想知道其余的在哪里 :) 所以我会继续关注 ;) 谢谢 @peci1 我今天介绍了 JCEKS 和 PKCS12。对于PKCS11,它涉及硬件和额外的配置,需要更多的时间来编写它。 pixelstech.net/article/… 和 pixelstech.net/article/… 哇,这真是闪电般的速度!非常感谢。【参考方案4】:

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

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

如果您已经有一个 PKCS#12 文件,直接使用 PKCS12 类型通常更容易。可以转换格式,但如果您可以直接选择密钥库类型,则很少需要。

在 Java 7 中,PKCS12 主要用作 keystore,但较少用作 truststore(请参阅 difference between a keystore and a truststore),因为您无法存储证书没有私钥的条目。相比之下,JKS 不要求每个条目都是私钥条目,因此您可以拥有仅包含证书的条目,这对于存储您信任的证书列表的信任存储很有用(但您不没有他们的私钥)。

这在 Java 8 中发生了变化,因此您现在也可以在 PKCS12 存储中拥有仅限证书的条目。 (有关这些更改和进一步计划的更多详细信息,请访问JEP 229: Create PKCS12 Keystores by Default。)

还有一些其他的密钥库类型,可能不太常用(取决于上下文),它们包括:

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

【讨论】:

@husayt,不直接支持 PEM 证书作为密钥库类型(我想可以为此编写一个 KeyStore 实现)。但是,您可以使用CertificateFactory(如this answer 所示)将它们即时加载到内存中的密钥库实例(通常是JKS,默认类型)中。 我认为JKS 已更改为JCEKS 更重要的是,JKS 密钥库不能存储密钥。对于这个用例,JCEKS 是合适的。在您的回答中可能值得一提。 好的。在 Java 8 中,我可以使用单个证书创建 PKCS#12 密钥库,而不会出现任何问题。请注意,对于 P12 证书条目是隐式信任的。如果您需要不受信任的证书,您可能必须恢复到具有多个密钥存储的方案。 OK 至少对于 Java 8 PKCS#12 密钥存储仍然无法存储密钥条目。存储这样的密钥库时会出现空指针异常(呃),可能是因为它找不到关联的证书。似乎有人跳过了 Joshua 关于快速失败代码的教导。

以上是关于密钥库类型:使用哪一种?的主要内容,如果未能解决你的问题,请参考以下文章

swift 中不同类型的闭包语法——哪一种是正确的?

使用 jwt-go 库 - 密钥无效或类型无效

您是哪一种类型的老板?

密钥库中条目类型“keyEntry”和“trustedCertEntry”之间的区别

用spss对数据进行回归分析,但不知选哪一种回归类型,怎么办?请教高手!

指令loadx是哪一种类型