密钥库/信任库中必须包含哪些内容才能进行相互身份验证?

时间:2014-05-08 16:29:05

标签: java ssl x509 keytool

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

客户端:

密钥库:

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

信任库:

  • 服务器的自签名证书。

服务器

密钥库:

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

信任库:

  • 服务器的自签名证书。

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

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

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

2 个答案:

答案 0 :(得分:3)

您的配置中存在一些错误。

查看调试日志,证书没有基本约束来表示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# 39; t匹配任何主机名。虽然默认SSLSocket默认情况下不进行任何主机名验证(您可以对其进行配置),但拥有服务器证书的有效主机名非常有用,因为客户端应该真正验证它原理

总的来说,对CA和服务器证书使用相同的证书似乎没有多大好处。自签名证书在单独使用时非常有用。如果您还计划将其用作CA证书,则可以将CA证书和服务器证书分开。从长远来看,它肯定是有用的,特别是当您必须更改服务器证书时,在2015年5月7日19:21:23 BST 2015"在您的示例中,或者您可能出于任何其他原因需要重新颁发服务器证书。

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

  • 客户端:

    • 密钥库:

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

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

    • 密钥库:

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

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

答案 1 :(得分:2)

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

  

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

,第二个是

  

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

另外还有一个好的博客here来阅读相同的