java - 信任库中的根证书是否足以建立连接?
问题描述
信任库中的根证书是否足以建立与网站的连接?如果是这样,只是为了测试,我已将谷歌的根证书导入到我创建并指向该信任存储的新信任存储中。即使这样,我也收到以下异常。
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
但是,如果我尝试使用默认的 java 信任库连接到谷歌,那么它工作正常。有人可以帮我吗?TIA。
解决方案
这是有关其工作原理的更详细答案:
在 TLS 握手过程中,服务器发送一个形成链的证书列表。在 TLS 1.2 RFC 5246中,它被解释为:
这是证书的序列(链)。发件人的证书必须在列表中排在第一位。后面的每个证书必须直接证明它前面的证书。因为证书验证要求根密钥是独立分发的,所以可以从链中省略指定根证书颁发机构的自签名证书,假设远程端必须已经拥有它才能在任何情况下验证它。
证书的根始终是自签名的,对于全球接受的根 CA(证书颁发机构),证书存储在客户端平台(即 Mozilla、MacOS、Java、Android、Windows 等)中。因此服务器不需要发送这个证书。
相同的 RFC 还提到:
实现负责验证证书的完整性,并且通常应该支持证书撤销消息。应始终验证证书以确保由受信任的证书颁发机构 (CA) 正确签名。应非常谨慎地选择和添加受信任的 CA。用户应该能够查看有关证书和根 CA 的信息。
换句话说,平台实现将遍历证书链并不断验证证书,直到找到信任库中的证书。信任存储中存在的任何证书都不会被验证,并将被假定为受信任的证书。
实现负责验证证书的完整性,并且通常应该支持证书撤销消息。如果没有来自应用程序配置文件的特定指示,则应始终验证证书以确保由受信任的证书颁发机构 (CA) 进行正确签名。信任锚的选择和添加应该非常谨慎。用户应该能够查看有关证书和信任锚的信息。
它进一步说:
自签名证书或信任锚证书上的签名未经过验证,因为它们开始了一条证书路径
现在,以 Google 为例,如果我们在https://www.ssllabs.com/中测试服务器,我们可以看到证书是由服务器发送的,而www.google.com
证书存在于平台的信任库中。GTS CA 101
GlobalSign
希望这能澄清我之前的评论。
推荐阅读
- azure - 从本地开发中的应用配置访问 Azure Key Vault 参考值
- nginx - 获取静态文件的正确路径以通过 nginx 为它们提供服务
- javascript - javascript for 循环:问题
- javascript - React 组件在获取新数据之前渲染旧状态
- python - 在 Macbook 上运行 Anaconda 时使用终端命令
- javascript - 自动在 CPT 中添加分类
- azure-devops - 如何获取我的 Azure DevOps 发布管道以从 Azure 存储帐户获取工件
- amazon-web-services - Elastic Beanstalk 在环境变量更新时失败
- javascript - 如何根据最大值和最小值按时间戳顺序创建对象数组?
- excel - 从 IE 升级到 EDGE