当前位置: 首页 > 知识库问答 >
问题:

服务器能否向客户端发送多个证书?

和谦
2023-03-14

我已经编写了小型Java 7客户端和服务器应用程序。我有3个自签名的X.509 RSA证书的密钥库。当客户端通过SSL连接时,服务器只发送一个证书的SSL证书消息。我对SSL/TLS有点陌生。我还研究了JSSE代码sun。安全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“找不到可信证书”。所以我的问题是,如果客户端请求的信息(来自ClientHello)与所有3个证书都匹配,为什么服务器不能发送所有3个证书?这是否与TLS 1.0与TLS 1.2有关?

共有2个答案

娄德运
2023-03-14

运气不好,你只能送一个。见RFC 2616

范文昌
2023-03-14

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

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

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\u 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.
 类似资料:
  • 我使用的是Netty 3.9.5,我有一个简单的客户机-服务器设置,我从http://en.wikipedia.org/wiki/Netty_(软件)#Netty\u TCP\u示例。我扩展了这个示例,将Java search plan对象从客户端发送到服务器。在这个网站上跟踪用户的帮助下,我已经能够让这个程序按预期运行。 现在,我想让我的读卡器/服务器程序同时接受多个客户端。我想我会使用下面列出

  • 我正在创建我的产品,并与这个问题。有一天,我设置了Socket.io,一切都很好。第二天,我将服务器和客户端从http迁移到HTTPS。迁移后客户端和服务器端仍然连接,但不能从客户端发射到服务器,从服务器发射到客户端。 我的ssl证书位于和中,它们加载正确。运行在上的服务器 我的示例react组件。我的react应用程序运行在上。HTTPS连接良好,工作良好。 我该怎么办?也许我在中错误地使用了s

  • 问题内容: 首先,我将请求的文件从服务器发送到客户端,然后再将文件的计算出的sha从服务器发送到客户端,以便客户端可以检查发送文件和接收文件中的sha是相同的。 我设法发送了文件,但是当我尝试也发送sha(这是一个变量)时,我收到一个错误消息(我相信sha也已添加到文件内容中) 如何分别发送? 和客户: 问题答案: 您应该重新设计应用程序的工作方式: 首先,服务器将文件大小发送给客户端 客户端读取

  • 我正在从服务器向客户端发送自定义web套接字帧。我成功地实现了无缝握手,但发送常规文本帧会给我带来问题(客户端的消息未被接收)。这是我发送的: 数据发送正确(握手成功,jj值为6)。我的代码基于这里的解释,如何在服务器端发送和接收WebSocket消息?。 我的客户非常简单,我只是为了完成发布: 我从客户端获得的Web套接字版本是13。 知道为什么握手有效而普通文本无效吗?

  • 问题内容: 所以现在,我正在制作一个基于客户端服务器应用程序的多线程。在服务器端,我为接受的每个连接创建了一个线程。 在线程类中,我创建了一种将命令发送到客户端的方法。我只想要的是如何将参数发送到所有正在运行的客户端?为简单起见,我只想使此服务器向所有连接的客户端发送消息。 我已经阅读了这篇文章,并从此链接中找到方法。但是,当我尝试使用自己的代码时,中没有类似的方法。 好的,这是我的服务器和线程示

  • 问题内容: 我将实现类似于Facebook通知和此网站的内容(StackOverflow的通知会通知我们是否有人为我们的问题写评论/答案等)。请注意,用户将使用我的应用程序作为网站而不是移动应用程序。 我遇到以下获取结果的答案,但我需要推送结果而不是获取结果。 根据建议,我在实体类中创建了一个简单方法,并向其中添加了@PostPersist,但此方法不起作用,因此基于此答案,我添加了persist