iOS 中对 HTTPS 证书链的验证 下载本文

内容发布更新时间 : 2024/6/3 20:12:55星期一 下面是文章的全部内容请认真阅读。

iOS 中对 HTTPS 证书链的验证

这篇文章是我一边学习证书验证一边记录的内容, 稍微整理了下,共扯了三部分内容: 1. 2. 3.

HTTPS 简要原理;

数字证书的内容、生成及验证; iOS 上对证书链的验证。

HTTPS 概要

HTTPS 是运行在 TLS/SSL 之上的 HTTP,与普通的 HTTP 相比,在数据传输的安全性上有很大的提升。

要了解它安全性的巧妙之处,需要先简单地了解对称加密和非对称加密的区别:

对称加密只有一个密钥,加密和解密都用这个密钥;

非对称加密有公钥和私钥,私钥加密后的内容只有公钥才能解密,公钥加密的内容只有私钥才能解密。

为了提高安全性,我们常用的做法是使用对称加密的手段加密数据。可是只使用对称加密的话,双方通信的开始总会以明文的方式传输密钥。那么从一开始这个密钥就泄露了,谈不上什么安全。所以 TLS/SSL 在握手的阶段,结合非对称加密的手段,保证只有通信双方才知道对称加密的密钥。大概的流程如下:

? ?

TSL:SSL_handshake.png 所以,HTTPS 实现传输安全的关键是:在 TLS/SSL 握手阶段保证仅有通信双方得到 Session Key!

数字证书的内容

X.509 应该是比较流行的 SSL 数字证书标准,包含(但不限于)以下的字段:

字段 值说明 对象名称(Subject Name) 用于识别该数字证书的信息 共有名称(Common Name) 对于客户证书,通常是相应的域名 证书颁发者(Issuer Name) 发布并签署该证书的实体的信息 签名算法(Signature Algorithm) 签名所使用的算法 序列号(Serial Number) 数字证书机构(Certificate Authority, CA)给证书的唯一整数,一个数字证书一个序列号 生效期(Not Valid Before) (`?ω?′) 字段 失效期(Not Valid After) (╯°口°)╯(┴—┴ 公钥(Public Key) 签名(Signature) 可公开的密钥 值说明 通过签名算法计算证书内容后得到的数据,用于验证证书是否被篡改 除了上述所列的字段,还有很多拓展字段,在此不一一详述。 下图为 Wikipedia 的公钥证书:

wikipedia_cer.png 数字证书的生成及验证

数字证书的生成是分层级的,下一级的证书需要其上一级证书的私钥签名。 所以后者是前者的证书颁发者,也就是说上一级证书的 Subject Name 是其下一级证书的 Issuer Name。

在得到证书申请者的一些必要信息(对象名称,公钥私钥)之后,证书颁发者通过 SHA-256 哈希得到证书内容的摘要,再用自己的私钥给这份摘要加密,得到数字签名。综合已有的信息,生成分别包含公钥和私钥的两个证书。 扯到这里,就有几个问题:

问:如果说发布一个数字证书必须要有上一级证书的私钥加密,那么最顶端的证书——根证书怎么来的?

根证书是自签名的,即用自己的私钥签名,不需要其他证书的私钥来生成签名。

问:怎么验证证书是有没被篡改?

当客户端走 HTTPS 访问站点时,服务器会返回整个证书链。以下图的证书链为例:

chain_hierarchy.png 要验证 *.wikipedia.org 这个证书有没被篡改,就要用到 GlobalSign Organization Validation CA - SHA256 - G2 提供的公钥解密前者的签名得到摘要 Digest1,我们的客户端也计算前者证书的内容得到摘要 Digest2。对比这两个摘要就能知道前者是否被篡改。后者同理,使用 GlobalSign Root CA 提供的公钥验证。当验证到到受信任的根证书时,就能确定 *.wikipedia.org 这个证书是可信的。

问:为什么上面那个根证书 GlobalSign Root CA 是受信任的? 数字证书认证机构(Certificate Authority, CA)签署和管理的 CA 根证书,会被纳入到你的浏览器和操作系统的可信证书列表中,并由这个列表判断根证书是否可信。所以不要随便导入奇奇怪怪的根证书到你的操作系统中。

问:生成的数字证书(如 *.wikipedia.org)都可用来签署新的证书吗?

不一定。如下图,拓展字段里面有个叫 Basic Constraints 的数据结构,里面有个字段叫路径长度约束(Path Length Constraint),表明了该证书能继续签署 CA 子证书的深度,这里为0,说明这个 GlobalSign Organization Validation CA - SHA256 - G2 只能签署客户端证书,而客户端证书不能用于签署新的证书,CA 子证书才能这么做。