PKCS12密钥库和PKCS11密钥库有什么区别?

39

我对Java-NSS库很感兴趣,正在阅读Sun's P11 Guide。我对以下内容感到困惑:

使用PKCS12密钥库和PKCS11密钥库有什么区别?

密钥库只是一个密钥库,是吗?它们有什么不同吗?它们可以在任何方面互换使用吗?


Bruno已经解释得很好了,所以我只想做一些评论。使用PKCS#12,您将提取密钥,然后仅使用Sun提供程序(或其他仅Java提供程序之一)处理它们即可。使用PKCS#11(这是一个完全不同的标准,PKCS只是公钥密码学标准的意思),密钥将保留在PKCS#11令牌内,因此将由本机PKCS#11库(或底层令牌)处理。因此,KeyStore不仅仅是一个密钥库。但是,如果Java代码足够兼容,则可以互换使用密钥/证书。 - Maarten Bodewes
@owlstead: 我不太清楚以下问题:PKCS11密钥库能否像PKCS12密钥库一样在keyManager中用作自身认证的keystore(在jsse中的ssl上下文中)以与其他方进行通信?还是说这是不可能的? - Cratylus
是的,您可以像使用其他KeyStore一样使用PKCS11 KeyStore,包括通过KeyManager和SSLContext。 - Bruno
2个回答

58

PKCS#12是一种文件格式(通常称为.p12或.pfx),您可以在其中存储私钥和证书,用于转换/传输密钥和证书。如果您从浏览器导出私钥+证书,则很可能会使用该格式。

PKCS#11是一个接口,通常用于与硬件加密令牌进行通信(通常是智能卡或USB令牌,实际上是嵌入读卡器中的智能卡)。此接口具有许多操作以利用密钥和证书。一些令牌能够使用它们包含的私钥进行签名,而不使密钥能够离开设备。 该接口的目的是将处理密钥和证书的内容视为单独的实体,而无需执行PKCS#11提供的加密操作(更具体地说,是与私钥相关的操作)。

当您在NSS中使用PKCS#11时,您实际上是在使用NSS作为包装在PKCS#11层后面的黑匣子(它实际上是PKCS#11硬件令牌的软件提供程序)。在Java中,通过PKCS#11使用NSS的方式有所不同,因为它不需要PKCS#11共享库(与其他PKCS#11库相比),因此它严格来说不是PKCS#11,尽管它非常相似。

在Java中,您可以从PKCS#11存储库中获取RSAPrivateKey实例,使用它进行签名和解密,而无需能够从其模数获得任何内容。处理它的安全提供程序将通过库(因此通过令牌)进行签名/解密。

回到Java中的KeyStore,它是一个API,可以允许您从文件(您可以根据安全提供程序获取各种文件格式,例如JKS、PKCS#12、PEM)或从其他底层API(例如PKCS#11,在Sun提供程序中与NSS更加合并,如果您正在使用KeyChain作为KeyStore,则在OSX上使用KeychainStore)中加载和使用密钥和证书。


如果您想使用 cert8.db,可以使用一个 PKCS11 KeyStore 配置来使用 NSS 并指向该文件(严格来说这不是 PKCS#11,但在 Java 中它与之非常接近)。您还可以以不同的方式配置 PKCS11 KeyStore,以使用 PKCS#11 共享库。总的来说,KeyStore 是一个更高级别的抽象,包括任何可以存储密钥/证书或通过其使用它们的内容。确实可以使用这样的 KeyStore 进行 SSL,前提是密钥类型正确(取决于密码套件):RSA 是相当常见的。 - Bruno
KeyStore 作为一个类,并不一定是一个具体的东西,而是一个可以用来与文件(JKS、P12)、令牌(PKCS#11)或其他库(KeychainStore、NSS)进行交互的实体。事实证明,NSS 的要求与 PKCS#11 消费者非常相似,因此它们被放在了一起。然后,如果需要,可以配置这些底层实体,例如指向 cert8.db 文件或使用某个智能卡槽。像 PKCS#12 文件这样的简单实体不需要进行任何此类配置。 - Bruno
@Bruno:NSS 的 Java 示例是针对 cert8.db 的。所以它就像一个硬件令牌一样被访问,是这样吗?我理解得对吗? - Cratylus
您可能也对这篇文章感兴趣:http://java.sun.com/developer/technicalArticles/J2SE/security/ - Bruno
1
这里并不重要是否认证。更重要的是NSS在Java之外(它是来自Mozilla的库),并且与实际的PKCS#11库有相似之处。因此,Sun已经将纯粹的PKCS#11和NSS的接口都实现到了PKCS11存储类型中。区别在于配置:使用"纯" PKCS#11时,你需要使用library = .../libpkcs11.so;而使用NSS时,需要指定nssLibraryDirectory = ...。NSS并不是为了通过PKCS11来使用,但是Java的PKCS11存储类型被扩展以支持NSS以及真正的PKCS#11库。 - Bruno
显示剩余3条评论

5
Java中不同类型的密钥库 -- 概述文章中可以得知,PKCS12和PKCS11之间的区别如下: PKCS12,这是一种标准的密钥库类型,可用于Java和其他语言。您可以在sun.security.pkcs12.PKCS12KeyStore找到这个密钥库实现。它通常具有p12或pfx扩展名。您可以在此类型上存储私钥、秘密密钥和证书。与JKS不同,PKCS12密钥库上的私钥可以在Java中提取。此类型是可移植的,并且可以与其他语言编写的库一起操作,例如C、C++或C#。
目前,在Java中默认的密钥库类型是JKS,即如果您在使用keytool创建密钥库时没有指定-storetype,则密钥库格式将为JKS。但是,由于与JKS相比具有增强的兼容性,因此在Java 9中,默认的密钥库类型将更改为PKCS12。您可以在$JRE/lib/security/java.security文件中检查默认密钥库类型。 PKCS11,这是一种硬件密钥库类型。它为Java库提供了一个接口,用于连接硬件密钥库设备,例如SafeNet的Luna、nCipher或智能卡。您可以在sun.security.pkcs11.P11KeyStore找到此实现。当您加载密钥库时,无需创建具有特定配置的特定提供程序。此密钥库可存储私钥、秘密密钥和证书。在加载密钥库时,条目将从密钥库中检索,然后转换为软件条目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接