首页 文章

Trust Store与Key Store - 使用keytool创建

提问于
浏览
205

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

I was interested though in understanding how / when you distinguish the stores when using 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") set,我可以在受信任的证书下看到证书(但不在密钥库部分下) . 我最好留下另一个问题的特定证书!) .

任何指示或澄清都将非常感激 . 无论你导入什么,keytool的输出都是相同的,它的惯例是一个是密钥库而另一个是信任存储?使用SSL等时的关系是什么?

5 回答

  • 282

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

    javax.net.ssl.keyStorejavax.net.ssl.trustStore 参数是用于构建 KeyManagerTrustManager (分别)的默认参数,然后用于构建 SSLContext ,其实质上包含通过 SSLSocketFactorySSLEngine 进行SSL / TLS连接时要使用的SSL / TLS设置 . 这些系统属性就是默认值的来源,然后由 SSLContext.getDefault() 使用,例如 SSLSocketFactory.getDefault() 使用它 . (如果你不想使用默认值和特定的 SSLContext 用于给定目的,所有这些都可以在许多地方通过API进行自定义 . )

    KeyManagerTrustManager (以及 javax.net.ssl.keyStorejavax.net.ssl.trustStore 之间)之间的差异如下(引自JSSE ref guide):

    TrustManager:确定是否应该信任远程身份验证凭据(以及连接) . KeyManager:确定要发送到远程主机的身份验证凭据 .

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

    本质上, javax.net.ssl.keyStore 中的密钥库旨在包含您的私钥和证书,而 javax.net.ssl.trustStore 旨在包含CA证书,您通常更好地使用不同的存储(特别是当它们基于文件时) .

  • 12

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

  • 22

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

    TrustStore:如名称所示,它通常用于存储可信实体的证书 . 进程可以维护其信任的所有可信任方的证书存储 . keyStore:用于存储服务器密钥(公共和私有)以及签名证书 .

    在SSL握手期间,

    • 客户端尝试访问https://

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

    • 现在,客户端收到SSL证书并通过trustStore进行验证(即客户端的trustStore已经拥有它信任的预定义证书集) . 它像:我可以信任这台服务器吗?这是我试图与之交谈的服务器吗?没有中间人攻击?

    • 一旦客户端验证它正在与它信任的服务器通信,则SSL通信可以通过共享密钥进行 .

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

  • 22

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

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

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

    • 自我认证证书:

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

    • 将证书导出到文件夹:

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

    • 将证书导入客户端Truststore:

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

  • 0

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

相关问题