【问题标题】:What must be contained in the keystores/truststores for mutual authentication?用于相互身份验证的密钥库/信任库中必须包含什么?
【发布时间】:2014-06-26 04:17:20
【问题描述】:

我正在尝试在 Java 中执行相互身份验证。我试图实现的结构是:具有自签名证书的服务器充当 CA,签署客户端证书。因此,这就是我在每个密钥库/信任库中保留的内容:

客户:

密钥库:

  • 客户端的 SSL 密钥对。
  • 服务器签署的证书(与密钥对相关)。

信任库:

  • 服务器的自签名证书。

服务器

密钥库:

  • 服务器的 SSL 密钥对。
  • 自签名证书(与密钥对相关)。

信任库:

  • 服务器的自签名证书。

我能够执行服务器的身份验证,但是当我在服务器上启用 setNeedClientAuth(true) 时,我在日志中收到以下错误: http://pastebin.com/raw.php?i=P52Qq89z 所以服务器似乎验证了,但客户端无法提供 CA 链,可能是它的 keystore 的内容有问题吗?

我使用 openSSL 生成密钥和证书,使用 KeyStore Explorer 创建密钥库(在使用 keytool 几天后不成功)和 JDK 1.7.0_51

更新:问题已按照以下说明解决:https://stackoverflow.com/a/12150604/2891462 CA 自签名证书的创建方式存在问题(显然,这只是 JDK 1.7 中的问题)。

【问题讨论】:

  • 自签名证书主要在单独使用时有用。如果您也打算将其用作 CA 证书,则不妨将 CA 证书和服务器证书分开。从长远来看,它肯定会有用。

标签: java ssl x509 keytool


【解决方案1】:

您的配置中有几处有问题。

查看您的调试日志,您的证书没有说 CA=true 的基本限制。

[
  Version: V1
  Subject: CN=Ficticious bank, OU=SoE, O=University, L=London, ST=England, C=UK
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
  Key:  Sun RSA public key, 2048 bits
  Validity: [From: Wed May 07 19:21:23 BST 2014,
               To: Thu May 07 19:21:23 BST 2015]
  Issuer: CN=Ficticious bank, OU=SoE, O=University, L=London, ST=England, C=UK
  SerialNumber: [    9a7143cf f5ecfbf8]

]
  Algorithm: [SHA1withRSA]
  ...
]

如果不是 CA 证书,它就不能作为 CA。请参阅RFC 3280(和 5280):

   This extension MUST appear as a critical extension in all CA
   certificates that contain public keys used to validate digital
   signatures on certificates.

其次,您还希望将其用作服务器的最终实体证书 (EEC) 的此证书没有该服务器的有效名称:没有主题备用名称和明显不匹配的 CN任何主机名。虽然默认 SSLSocket 默认不做任何主机名验证(您可以配置它),但为服务器证书提供一个有效的主机名很有用,因为原则上客户端应该真正验证它。

总体而言,为 CA 和服务器证书使用相同的证书似乎没有太多好处。自签名证书主要在单独使用时有用。如果您也打算将其用作 CA 证书,则不妨将 CA 证书和服务器证书分开。从长远来看,它肯定会很有用,特别是当您必须更改服务器证书时,在您的示例中的“Thu May 07 19:21:23 BST 2015”,或者您可能需要重新颁发服务器证书出于任何其他原因。

除此之外,您对密钥库和信任库有正确的想法:

  • 客户:

    • 密钥库:

      • 客户端私钥和证书链在同一个条目中(但 CA 证书本身可以省略)。
    • 信任库:

      • 可以验证服务器证书的 CA 证书。
  • 服务器

    • 密钥库:

      • 服务器私钥和证书链在同一个条目中(但 CA 证书本身可以省略)。
    • 信任库:

      • 可以验证客户端证书的 CA 证书。

【讨论】:

  • 非常感谢。确实,自签名证书的生成方式有问题,我更新了原帖。我将改变结构,使服务器的证书也由独立的CA签名,并研究CN主机名验证。
  • 如果您不太确定keytool 选项,您可能会发现XCA 非常有用。请记住,您可以通过选择 PKCS12 密钥库类型直接在 Java 中使用 PFX/P12 文件。
  • 关于主机名验证,您可能对thisthis感兴趣。
【解决方案2】:

对于相互认证(2 路 SSL)只需要做两件事

从服务器的密钥库导出的服务器证书(不信任存储 - 如果您使用不同的信任和密钥存储)

第二个是

客户端的证书应该存在于服务器的信任库中(不是密钥 存储 - 如果您使用不同的信任和密钥存储)

另外还有一个很好的博客here 可以阅读相同的内容

【讨论】:

  • 谢谢。如果我专门将客户端的证书添加到服务器的信任库,我可以让它工作。但是,我不想添加所有客户的证书,而是说“如果客户提供的证书是我签名的,请接受”。所以我的问题是客户端显然无法提供证书链,对吧?
  • 我刚刚发现了一些有趣的东西:stackoverflow.com/questions/11153058/…我稍后会尝试并评论它。
  • 是的,这就是问题所在:我重新生成了 CA .crt,更新了客户端的密钥库和服务器的信任库,它可以工作了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2019-11-28
  • 2013-02-15
相关资源
最近更新 更多