目前出现一个bug:网络设备代理https 进行ssl卸载时出现一个问题,证书校验失败问题;原因是目前设备的证书没有带上root ca;导致客户端校验证书失败!
现在看看证书校验逻辑!文章转载自
三、证书校验
这一节对前文 2.6证书校验
提到的证书校验流程进行详细介绍:
- 1、X.509数字证书结构举例
- 2、客户端 如何校验服务端下发的公钥证书?
3.1、X.509数字证书
了解证书校验原理之前,先认识一下X.509证书的结构。
X.509
是密码学里公钥证书
的格式标准
,当前X.509
证书已应用在包括TLS/SSL
在内的众多网络协议里。
一个具体的X.509 v3数字证书结构大致如下 :
// X.509数字证书 Certificate // 版本号 Version Number // 序列号 Serial Number // 证书签名算法ID Signature Algorithm ID // 证书发行者 Issuer Name // 证书有效时间 Validity period // 证书主体名称 Subject name // 证书主体公钥信息 Subject Public Key Info // 证书公钥算法 Public Key Algorithm // 证书公钥 Subject Public Key // 发行商唯一ID Issuer Unique Identifier (optional) // 主体唯一ID Subject Unique Identifier (optional) // 扩展 Extensions (optional) // 证书签名算法 Certificate Signature Algorithm // 证书签名值 Certificate Signature
3.2、证书校验
客户端验证服务端下发的证书,主要包括以下几个方面:
- 1、校验证书是否是
受信任
的CA根证书
颁发机构颁发; - 2、校验证书是否在上级证书的
吊销列表
; - 3、校验证书
是否过期
; - 4、校验证书
域名
是否一致
。
3.2.1、证书可信性
校验证书是否可信:
校验证书是否是由受信任的CA根证书颁发机构颁发。
为了确保客户端
获取到的服务端公钥
不被篡改,需引入权威的第三方CA机构。
CA机构负责核实
公钥拥有者
信息、颁发证书
(对服务端公钥进行签名)、同时为使用者提供证书验证
服务。
CA机构 颁发证书的基本原理:
服务端
生成一对公钥
、私钥
。服务端
将自己的公钥提供给CA机构
。CA机构
核实服务端公钥
拥有者信息:
核实申请者提供信息的真实性:如组织是否存在、企业是否合法、是否拥有域名的所有权等。CA机构
签发证书:
CA机构 计算 服务器公钥摘要信息
,然后利用CA机构私钥
(CA机构有一对公钥、私钥)加密摘要信息
。
加密后的包含加密摘要
信息的服务端公钥
即CA机构
颁发的证书
。
客户端 验证服务端公钥的基本原理为:
客户端
获取到服务端的公钥
:
Https请求 TLS握手过程中,服务器公钥会下发到请求的客户端。客户端
用存储在本地的CA机构的公钥
,对服务端公钥
中对应的摘要信息
进行解密,获取到服务端公钥
的摘要信息A
;客户端
根据对服务端公钥
进行摘要计算,得到摘要信息B
;对比
摘要信息A与B
,相同则证书验证通过;
3.2.2、证书吊销
CA机构
能够签发证书
,同样也存在机制宣布
以往签发的证书无效
。若证书的申请主体出现:私钥丢失
、申请证书无效
等情况,CA机构需要废弃该证书。
主要存在两类机制:CRL 与 OCSP。
- CRL(Certificate Revocation List)
证书吊销列表:是一个单独的文件,该文件包含了 CA机构 已经吊销的证书序列号与吊销日期;
证书中一般会包含一个 URL 地址CRL Distribution Point
,通知使用者去哪里下载对应的 CRL 以校验证书是否吊销。
该吊销方式的优点是不需要频繁更新,但是不能及时吊销证书,因为 CRL 更新时间一般是几天,这期间可能已经造成了极大损失。 - OCSP(Online Certificate Status Protocol)
证书状态在线查询协议:一个实时查询证书是否吊销的方式。
请求者发送证书的信息并请求查询,服务器返回正常、吊销或未知中的任何一个状态。
证书中一般也会包含一个 OCSP 的 URL 地址,要求查询服务器具有良好的性能。
部分 CA 或大部分的自签 CA (根证书)都是未提供 CRL 或 OCSP 地址的,对于吊销证书会是一件非常麻烦的事情。
3.2.3、证书过期
校验证书的有效期是否已经过期:主要判断证书中Validity period
字段是否过期。
3.2.4、证书域名
校验证书域名是否一致:核查
证书域名
是否与当前的访问域名
匹配
。
举例中:
我们请求的域名 www.baidu.com 是否与证书文件
中DNS标签
下所列的域名
相匹配
;
一种错误的写法:
Android 软件开发中,我们经常会遇到以下代码,用来忽略证书的域名验证,其实这是一种不安全的写法:
// 对于自签名证书,用以下代码来忽略证书的域名验证
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
// 忽略证书的域名验证
return true;
}
};
四、证书链校验
上一节介绍证书校验场景,适用于服务器证书
的签发机构就是Ca机构
。
实际证书申请中,由于权威的CA机构
数量不多,若所有的服务器证书
都向权威CA机构申请,那么CA机构的工作量就会非常大。因此CA机构采取授权
二级机构
的方式来管理证书申请,经授权
的二级机构
也可以签发服务器证书
。
4.1、证书链校验
证书签发:
根证书
CA机构 使用自己的私钥
对中间证书
进行签名,授权中间机构
证书;中间机构
使用自己的私钥
对服务器证书
进行签名,从而授权服务器证书
。
证书校验:
客户端
通过服务器证书
中签发机构信息
,获取到中间证书公钥
;利用中间证书公钥
进行服务器证书
的签名验证。
a、中间证书公钥解密 服务器签名,得到证书摘要信息;
b、摘要算法计算 服务器证书 摘要信息;
c、然后对比两个摘要信息。客户端
通过中间证书
中签发机构信息
,客户端本地查找到根证书公钥
;利用根证书公钥
进行中间证书
的签名验证。
4.2、中间证书怎么获取?
这里可能大家有一个疑问,根证书是内置在终端设备上或浏览器中的,那中间机构证书怎么获取?
这里仍以百度
的Tls证书
进行举例,百度服务器证书
签发者公钥
(中间机构公钥)通过下图中的URI获取:
线上问题:安卓部分手机出现ssl握手异常,苹果及PC访问正常
原因证书问题;不同平台的浏览器当发现服务器没有返回中间CA证书时,并没有统一的处理方式,有些浏览器比如windows平台或者IOS平台会根据证书中的“Authority Information Access"扩展字段提供的CA证书URL去自动下载中间CA证书, 从而完成证书链的校验,但有些平台,比如Android系统,如果服务器不返回中间CA证书,并不会去自动下载,而是直接报错。
SSL_CTX_use_certificate_chain_file() loads a certificate chain from file into ctx. The certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA. There is no corresponding function working on a single SSL object.
证书顺序为:
服务器证书->签名CA->根CA的顺序
当然需要确认签名CA的有效性,如果不是签名CA或者过期了,或者顺序不对该接口只会加载服务器证书到certificate中。
导致签名CA没有发送客户端,而一些客户端api接口需要这个CA来做校验,而导致访问失败
检查证书链是否完整可以通过openssl命令来检查,网上也有很多在线的工具可以检查,例如:https://www.ssllabs.com,
如果是openssl可以运行“openssl s_client -connect domain:443”进行检查,“domain”是你要检查的站点域名,比如
openssl s_client -connect www.baidu.com:443
自己搭建的服务器: