是否可以使用SSL连接到站点,其中客户端只有根证书,但服务器同时具有根证书和中间证书?
我正在尝试使用HttpUrlConnection与包含我的根的TrustManager进行连接,并且我得到了通常的握手错误:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
Certificate chaining error
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
我知道一般的解决方案是安装中间证书,但我想避免不断一次性获取供应商X的新中间证书。
我熟悉使用接受所有内容的TrustManager,但这不是一个选项。
答案 0 :(得分:13)
是否可以使用仅限客户端的SSL连接到站点 有根证书,但服务器有根和 中级证书?
这不仅是可能的,而且实际上是TLS工作的常用方式:
lib/security/cacerts
读取它们。浏览器要么拥有自己的内部列表,要么使用操作系统提供的列表。我知道一般的解决方案是安装中间件 证书
不,实际上没有,如上所述,服务器应该自动发送所有中间证书。
<强>然而强>
服务器上一个相当常见的配置错误是不在服务器上安装所有中间证书。在这种情况下,服务器将在连接设置期间发送不完整的证书链。然后客户端将无法构建有效的证书路径,并将中止连接。
一些并发症可能会使这个问题难以诊断:
诊断这些问题的有用工具:
openssl s_client -showcerts -connect google.com:443
section 7.4.2 of RFC 5246的相关引用:
7.4.2。服务器证书
发送此消息时:
服务器必须在约定的时间发送证书消息 密钥交换方法使用证书进行身份验证(这个 包括本文档中定义的所有密钥交换方法除外 DH_anon)。此消息将始终紧跟在ServerHello之后 消息。
此消息的含义:
此消息将服务器的证书链传达给客户端。
[...]
此消息的结构:
[...]
certificate_list
这是证书的序列(链)。发件人的证书 必须在列表中排在第一位。每个以下证书必须直接 证明前面的那个。因为证书验证需要 根密钥是独立分发的,自签名的 可以指定根证书颁发机构的证书 在远程端必须假设的情况下从链中省略 已经拥有它以便在任何情况下验证它。
答案 1 :(得分:6)
服务器应在Certificate
消息中发送整个证书链,包括中间证书。客户端将检查整个链并找到它信任的根证书。所以你所描述的应该有效。
当然,有可能(错误)配置服务器不发送整个链 - 在这种情况下,客户端的检查可能会失败。
答案 2 :(得分:3)
如this answer中所述:
使用Oracle JRE,您可以使用Java系统属性-Dcom.sun.security.enableAIAcaIssuers=true
来自动下载中间证书
要使其正常工作,服务器的证书必须提供URI给中间证书(证书的颁发者)。
答案 3 :(得分:-3)
当服务器具有由根CA(例如Verisign)签名的sub-ca-A签名的证书时,服务器将作为服务器hello的一部分发送所有证书,以便服务器的证书可以是验证。
在您的情况下,您只在信任库中拥有根CA.
因此,由于您缺少sub-ca证书,因此无法启动信任验证链 这不仅是不可能的,能够做到这一点是错误的/不安全的。所以你正在做的是摆脱正确的道路。
所以你只有两个选择 将信任库中的服务器的实际证书作为可信任的 将整个链放在信任库中,即中间CA证书和根。
你有什么顾虑?中级证书到期?