信任库与密钥库-使用keytool创建


249

据我了解,密钥库通常会保存私钥/公钥,而信任库通常只保存公钥(并且代表您打算与之通信的受信任方的列表)。好吧,这是我的第一个假设,因此,如果这不正确,那么我可能起步并不顺利...

不过,我很想了解使用keytool时如何/何时区分商店。

因此,到目前为止,我已经使用

keytool -import -alias bob -file bob.crt -keystore keystore.ks

这将创建我的keystore.ks文件。我回答yes了我是否信任bob的问题,但是我不清楚这是否创建了密钥库文件或信任库文件?我可以将我的应用程序设置为使用该文件。

-Djavax.net.ssl.keyStore=keystore.ks -Djavax.net.ssl.keyStorePassword=x
-Djavax.net.ssl.trustStore=keystore.ks -Djavax.net.ssl.trustStorePassword=x

并与System.setProperty( "javax.net.debug", "ssl")设置,我可以看到根据该证书信任认证(但不是下的密钥库部分)。我要导入的特定证书只有一个公共密钥,我打算用它通过SSL连接将数据发送给Bob(但这也许是另一个问题了!)。

任何指针或澄清将不胜感激。无论您导入什么,keytool的输出是否都是相同的,并且它的公正约定说一个是密钥库,另一个是信任库?使用SSL等时有什么关系?


我不确定“我要导入的特定证书只有一个公钥”是什么意思:是公钥(即不是证书)还是非CA证书?
布鲁诺

嗯,不确定。我从浏览器中导出为PEM文件。有帮助吗?
Toby

如果是从浏览器导出的,则可能是证书。它是服务器证书(CN或subjectAltName与服务器名称匹配)吗?它是CA证书吗(请在“基本约束”下查看,您应该可以使用浏览器查看此证书)。
布鲁诺

2
tl; dr:信任库包含公共的,受信任的根(CA)证书,而身份/密钥库包含的是私有的,身份证书;在文件方面,它们是相同的。
安德鲁

Answers:


346

该术语是有点混乱确实,但两者javax.net.ssl.keyStorejavax.net.ssl.trustStore用来指定密钥库来使用,用于两个不同的目的。密钥库有多种格式,甚至不一定是文件(请参阅此问题),keytool它只是一种对密钥库执行各种操作(导入/导出/列表/ ...)的工具。

javax.net.ssl.keyStorejavax.net.ssl.trustStore参数用于建立默认参数KeyManagerS和TrustManagerS(分别地),然后用于构建SSLContext制备SSL经由/ TLS连接时,其基本上包含SSL / TLS设置来使用SSLSocketFactorySSLEngine。这些系统属性正是默认值的来源,然后SSLContext.getDefault()SSLSocketFactory.getDefault()(例如)自身使用。(如果您不想将默认值和特定的SSLContexts用于给定目的,则可以在许多地方通过API定制所有这些。)

的之间的差KeyManagerTrustManager(并因此之间javax.net.ssl.keyStorejavax.net.ssl.trustStore)如下(从引JSSE REF指南):

TrustManager:确定是否应该信任远程身份验证凭据(以及连接)。

KeyManager:确定要发送到远程主机的身份验证凭据。

(其他参数可用,并且它们的默认值在JSSE参考指南中进行了描述。请注意,尽管信任存储有一个默认值,但密钥存储没有一个默认值。)

本质上,其中的密钥库javax.net.ssl.keyStore旨在包含您的私钥和证书,而密钥库则包含javax.net.ssl.trustStore当远程方出示证书时您愿意信任的CA证书。在某些情况下,它们可以是一个存储库,并且可以是同一存储库,尽管通常最好使用不同的存储库(尤其是基于文件的存储库)。


感谢您的答复,它可以使您的工作更加轻松。我仍然很困惑,但是在使用上,我可以使用pk12 pri / pub密钥(xxx.p12)作为密钥库(通过-D)并创建SSL连接(受信任),而无需通过-提及信任库D ...哦。
Toby

57
您不需要指定信任库,因为它有一个默认值(它与JRE捆绑在一起),通常位于$JAVA_HOME/lib/security/cacerts(请参阅我发送的第二个JSSE参考指南链接)。与浏览器一样,它包含一组默认的受信任CA证书。通常,客户端将始终使用信任库来检查服务器证书,但仅在服务器请求客户端证书时才使用密钥库,并且服务器将始终对其自身的密钥+证书使用密钥库,但信任库仅用于客户端发送客户端证书时使用。
布鲁诺

2
感谢您提供有用的信息。在Weblogic中,有一个“身份密钥库”存储服务器的SSL证书,然后有一个“信任密钥库”存储服务器信任的SSL证书,所以我说“身份密钥”是否正确? -store”仅是“密钥库”,而“ trust-key-store”仅是“ truststore”?
hagrawal

@Bruno还应该注意,当有“ jssecacerts”时,“ cacerts”会被忽略吗?
kommradHomer

61

以常见的用例/目的或外行方式进行解释:

TrustStore:顾名思义,它通常用于存储受信任实体的证书。流程可以维护其信任的所有信任方的证书存储。

keyStore:用于存储服务器密钥(公共和私有)以及签名证书。

在SSL握手期间,

  1. 客户端尝试访问https://

  2. 因此,服务器通过提供SSL证书(存储在其keyStore中)进行响应

  3. 现在,客户端收到SSL证书并通过trustStore对其进行验证(即,客户端的trustStore已经具有其信任的预定义证书集)。就像:我可以信任此服务器吗?这是我要与之交谈的服务器吗?没有中间人袭击?

  4. 一旦客户端验证了它正在与它信任的服务器进行通信,那么SSL通信就可以通过共享密钥进行。

注意:我在这里没有谈论服务器端的客户端身份验证。如果服务器也要进行客户端身份验证,则服务器还将维护一个trustStore来验证客户端。


25

密钥库文件和信任库文件之间没有区别。两者都是专有JKS文件格式的文件。区别在于使用:就我所知,Java仅会-Djavax.net.ssl.trustStore在创建SSL连接时使用系统属性引用的存储来查找要信任的证书。键和相同-Djavax.net.ssl.keyStore。但是从理论上讲,对信任库和密钥库使用同一个文件是可以的。


4
您可以通过设置javax.net.ssl.keyStoreTypejavax.net.ssl.trustStoreType系统属性来使用不同类型的密钥库(例如PKCS12)。
Donal Fellows

1
@Donal:很好的补充。您是否知道是否有所有受支持容器的列表?我只知道PKCS12和JKS(前者是反复试验的结果...)。
musiKk 2011年

2
密钥库格式取决于可用的提供程序(默认情况下,与Oracle JRE捆绑的提供程序请参见此列表)。这个问题也有讨论。其他提供程序(例如BouncyCastle)可以用于其他格式。
布鲁诺

21

服务器使用密钥库来存储私钥,第三方客户端使用信任库来存储服务器提供的用于访问的公钥。我已经在生产应用程序中做到了这一点。以下是生成用于SSL通信的Java证书的步骤:

  1. 在Windows中使用keygen命令生成证书:

keytool -genkey -keystore server.keystore -alias mycert -keyalg RSA -keysize 2048 -validity 3950

  1. 自我认证证书:

keytool -selfcert -alias mycert -keystore server.keystore -validity 3950

  1. 将证书导出到文件夹:

keytool -export -alias mycert -keystore server.keystore -rfc -file mycert.cer

  1. 将证书导入客户端Truststore:

keytool -importcert -alias mycert -file mycert.cer -keystore truststore


嗨,我有一个场景,其中我在同一容器(tomcat)中有两个不同的应用程序。在这两个应用程序中,我都必须从两端调用其余端点到每个应用程序。就像,从A到B,从B到A(A和B是两个应用程序)。在这种情况下是否需要使用信任库?因为我正在使用使用密钥库的自定义REST客户端。请提出建议。
迪帕克

0

这些是使用Keytool在本地计算机上创建信任库的步骤。在本地计算机中为URL创建信任库的步骤。

1)在浏览器中使用chrome浏览网址

2)检查镶边中网址左侧的“ i”图标,然后单击它

3)检查证书选项,然后单击它,将打开一个对话框

4)检查“证书路径”选项卡上可用于创建信任库的证书数量

5)转到"details" tab -> click"Copy to File" -> Give the path and the name for the certificate您要创建的。

6)检查它是否具有父证书,并遵循点“ 5”

7)创建所有证书后,打开“命令提示符”,然后导航到创建证书的路径。

8)提供以下Keytool命令以添加证书并创建信任库。

Sample: 
   keytool -import -alias abcdefg -file abcdefg.cer -keystore cacerts
        where "abcdefg" is the alias name and "abcdefg.cer" is the actual certificate name and "cacerts" is the truststore name

9)为所有证书提供keytool命令,并将它们添加到信任库中。

    keytool -list -v -keystore cacerts

-1

密钥库只存储私钥,而信任库则存储公钥。您将要生成用于SSL通信的Java证书。您可以在Windows中使用keygen命令,这可能是最简单的解决方案。


信任库存储受信任的证书。
罗恩侯爵

-1

简单来说:

密钥库用于存储您的凭据(服务器或客户端),而信任库用于存储其他凭据(来自CA的证书)。

在SSL上设置服务器端时,需要使用密钥库,该密钥库用于存储服务器的身份证书,该服务器将在连接上向客户端提供该服务器的证书,而客户端上的信任库设置必须包含该密钥才能使连接正常工作。如果浏览器通过SSL连接到任何网站,它将根据服务器的信任库验证服务器提供的证书。

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.