ssl - 服务器可以向客户端发送多个证书吗?

标签 ssl https client-server ssl-certificate tls1.2

我编写了小型 Java 7 客户端和服务器应用程序。我有包含 3 个自签名 X.509 RSA 证书的 keystore 。当客户端通过 SSL 连接时,服务器只发送一个证书的 SSL 证书消息。我对 SSL/TLS 有点陌生。我还查看了 JSSE 代码 sun.security.ssl.X509KeyManagerImpl,发现以下注释:

/*
 * Return the best alias that fits the given parameters.
 * The algorithm we use is:
 *   . scan through all the aliases in all builders in order
 *   . as soon as we find a perfect match, return
 *     (i.e. a match with a cert that has appropriate key usage
 *      and is not expired).
 *   . if we do not find a perfect match, keep looping and remember
 *     the imperfect matches
 *   . at the end, sort the imperfect matches. we prefer expired certs
 *     with appropriate key usage to certs with the wrong key usage.
 *     return the first one of them.
 */
private String More ...chooseAlias(List<KeyType> keyTypeList,
        Principal[] issuers, CheckType checkType)

评论很清楚,服务器将发送单个最佳匹配证书,但我似乎不明白原因。就像我的情况一样,我希望服务器发送所有 3 个证书,以便客户端可以选择一个并验证链。而且,如果我的客户端没有服务器发送的证书,连接将被丢弃,并显示 SSLHandshakeException 'No trusted certificate found'。所以我的问题是,如果客户端请求的信息(来自 ClientHello)与所有 3 个证书匹配,为什么服务器不能发送所有 3 个证书?它与 TLS 1.0 和 TLS 1.2 有关吗?

最佳答案

TLS 握手协议(protocol)仅提供一个客户端实体证书的传输(服务器证书也是如此)。 中间 证书可以传输,但您似乎想要的 - 传输多个终端实体证书 - 是不可能的。

TLS 服务器/客户端证书 消息的结构在 RFC 5246 (TLS 1.2) section 7.4.2 中定义:

Structure of this message:

      opaque ASN.1Cert<1..2^24-1>;

      struct {
          ASN.1Cert certificate_list<0..2^24-1>;
      } Certificate;

   certificate_list
      This is a sequence (chain) of certificates.  The sender's
      certificate MUST come first in the list.  Each following
      certificate MUST directly certify the one preceding it.  Because
      certificate validation requires that root keys be distributed
      independently, the self-signed certificate that specifies the root
      certificate authority MAY be omitted from the chain, under the
      assumption that the remote end must already possess it in order to
      validate it in any case.

关于客户端选择提供哪个证书,如果您将服务器配置为通告其受信任的 CA 以进行客户端证书验证(CertificateRequest 消息的 certificate_authorities 字段; 见下文),那么选择要呈现的证书的客户端代码应该选择一个由公布的 CA 之一认证的证书。

7.4.4.  Certificate Request

   ...

   Structure of this message:

      enum {
          rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
          rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),
          fortezza_dms_RESERVED(20), (255)
      } ClientCertificateType;

      opaque DistinguishedName<1..2^16-1>;

      struct {
          ClientCertificateType certificate_types<1..2^8-1>;
          SignatureAndHashAlgorithm
            supported_signature_algorithms<2^16-1>;
          DistinguishedName certificate_authorities<0..2^16-1>;
      } CertificateRequest;

   ...

   certificate_authorities
      A list of the distinguished names [X501] of acceptable
      certificate_authorities, represented in DER-encoded format.  These
      distinguished names may specify a desired distinguished name for a
      root CA or for a subordinate CA; thus, this message can be used to
      describe known roots as well as a desired authorization space.  If
      the certificate_authorities list is empty, then the client MAY
      send any certificate of the appropriate ClientCertificateType,
      unless there is some external arrangement to the contrary.

并且,从第 7.4.6 节开始:

  If the certificate_authorities list in the certificate request
  message was non-empty, one of the certificates in the certificate
  chain SHOULD be issued by one of the listed CAs.

关于ssl - 服务器可以向客户端发送多个证书吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31898059/

相关文章:

security - 在公共(public) Web 应用程序上使用客户端证书代替密码

.htaccess - 将 http 重定向到 https

c#-4.0 - 客户端和服务器之间不支持 TLS 1.0

audio - Shoutcast 服务器和客户端如何处理 mp3 帧头和帧依赖关系?

asp.net-mvc-3 - Controller 操作之外的 ASP.Net MVC 3 IF 语句

ssl - Mosquitto TLS,适用于 MQTTfx 但不适用于 mosquitto_pub(tlsv1 警报未知 ca)

java - SSL:两个 DNS 名称、1 个 IP、2 个证书 - Java 只看到 1 并提示

ruby - 使用 Ruby 脚本通过 https 登录网站

c - 服务器-客户端线程接受错误/泄漏

c++ - 强制 recv (Windows C++) 函数阻塞,直到读取 N 个字节