Trust Store与Key Store - 使用keytool创建

问题描述 投票:223回答:6

我知道密钥库通常会保存私钥/公钥,信任库只保存公钥(并代表您打算与之通信的可信方列表)。嗯,这是我的第一个假设,所以如果这不正确,我可能还没有开始......

我对使用keytool时如何/何时区分商店感兴趣。

所以,到目前为止,我已经创建了一个密钥库

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

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

-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等时的关系是什么?

java ssl keytool jce
6个回答
317
投票

这个术语确实有点令人困惑,但javax.net.ssl.keyStorejavax.net.ssl.trustStore都用于指定使用哪个密钥库,用于两个不同的目的。密钥库有各种格式,甚至不一定是文件(参见this question),而keytool只是对它们执行各种操作的工具(import / export / list / ...)。

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

TrustManagerjavax.net.ssl.keyStore之间的差异(以及javax.net.ssl.trustStoreJSSE ref guide之间的差异)如下(引自JSSE ref guide):

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

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

(其他参数可用,其默认值在javax.net.ssl.keyStore中描述。请注意,虽然信任库存在默认值,但密钥库中没有一个。)

本质上,javax.net.ssl.trustStore中的密钥库旨在包含您的私钥和证书,而javax.net.ssl.trustStore旨在包含您在远程方提供其证书时愿意信任的CA证书。在某些情况下,它们可以是同一个商店,尽管使用不同的商店通常是更好的做法(特别是当它们是基于文件的时候)。


43
投票

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

TrustStore:如名称所示,它通常用于存储可信实体的证书。进程可以维护其信任的所有可信任方的证书存储。

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

在SSL握手期间,

  1. 客户端尝试访问https://
  2. 因此,服务器通过提供SSL证书(存储在其keyStore中)进行响应
  3. 现在,客户端收到SSL证书并通过trustStore进行验证(即客户端的trustStore已经拥有它信任的预定义证书集)。它像:我可以信任这台服务器吗?这是我试图与之交谈的服务器吗?没有中间人攻击?
  4. 一旦客户端验证它正在与它信任的服务器通信,则SSL通信可以通过共享密钥进行。

注意:我在这里不是在谈论服务器端的客户端身份验证。如果服务器也想要进行客户端身份验证,那么服务器还会维护一个trustStore来验证客户端。


23
投票

密钥库和信任库文件之间没有区别。两者都是专有JKS文件格式的文件。区别在于使用:据我所知,Java将仅使用javax.net.ssl.keyStore引用的商店来查找创建SSL连接时要信任的证书。键和keytool -genkey -keystore server.keystore -alias mycert -keyalg RSA -keysize 2048 -validity 3950相同。但理论上,可以将同一个文件用于信任和密钥库。


21
投票

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

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

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

  1. 自我认证证书:

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

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

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

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

qazxswpoi


-1
投票

简单来说:

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

在SSL上设置服务器端时需要密钥库,它用于存储服务器的身份证书,服务器将在连接上呈现给客户端,而客户端上的信任存储设置必须包含以使连接起作用。如果您浏览器通过SSL连接到任何网站,它将验证服务器针对其信任库提供的证书。


-2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.