文章目录
前篇博文: TLS 加密原理中介绍了TLS 如何保证通信的机密性、完整性和真实性,如何完成共享密钥的协商交换,如何确认通信对端的真实性等问题。但面对中间人攻击时,仍存在“无法确认用于验证签名的公钥是否属于真正的通信对端?”的问题,不过也提出了解决思路,引入可信的第三方对公钥进行签名(经可信第三方签名认证的公钥可以称为证书),证书是如何解决公钥真实性的问题的呢?且看下文分解。
二、TLS 握手协议
2.1 证书与 PKI
前文介绍的ECDHE(Elliptic-Curve Diffie–Hellman Ephemeral)密钥协商方案可以实现认证加密算法(比如AES-GCM)共享密钥的交换,但密钥协商过程容易遇到中间人攻击问题。通过引入数字签名(比如ECDSA / RSA)可以确认通信对端的身份,但要正确使用数字签名,前提就是用于验证签名的公钥必须属于真正的通信对端,该如何确认自己得到的公钥是真实合法的呢?
很容易想到的一个思路是引入可信第三方背书,就像买家与卖家之间引入支付宝类似,将要传递的公钥经由可信第三方签名(经过可信第三方签名的公钥可以称为证书或公钥证书),只要我们能使用可信第三方公钥验证公钥证书,就可以确认公钥证书内的公钥是合法的。我们又如何传递可信第三方公钥呢?由于可信第三方属于中心化组织,全球需要的可信第三方数量很有限,因此可以将可信第三方的公钥集成到操作系统或浏览器中,不需要再额外传递。
但为了防止攻击者也申请一个公钥证书伪装通信对端,公钥证书内除了包含订阅人(申请公钥证书的一方)的公钥,还应包含订阅人的身份信息(比如域名Host 信息),当然也应该包含可信第三方(也即证书颁发机构Certificate Authority)的数字签名信息。可以说,公钥证书或数字证书是一个主要包含订阅人公钥、订阅人身份信息、证书颁发者数字签名等相关信息的数字文件,也就是一个让我们可以交换、存储和使用通信对端公钥的壳。
公钥证书或数字证书是由认证机构(CA: Certificate Authority)颁发的,使用者需要对证书进行验证,如果证书的格式千差万别那就不方便了。于是,人们制定了证书的标准规范,其中使用最广泛的是由 ITU(International Telecommunication Union)定义,经PKIX(Public-Key Infrastructure standards for X.509)工作组改造过的X.509规范(RFC5280)。
符合X.509标准的公钥证书不止包含订阅人公钥、订阅人身份信息、证书颁发者数字签名信息,还包括更多别的字段信息,我们以 https 证书为例,使用Microsoft Chromium Edge浏览器 --> 更多工具 --> 开发人员工具 --> 安全,可以查看到证书状态与安全连接设置,点击“查看证书”可以看到证书的基本/常规信息:
我们查看证书的详细信息,看标准的公钥证书一般包含哪些字段:
前面偏黄色的字段是版本V1 支持的基本字段,后面的属于扩展字段,下面给出几个主要字段的作用描述:
字段 | 描述 |
---|---|
序列号 | 每个CA用来唯一标识其所签发的证书,需要是无法被预测的而且至少包括20位 |
签名算法 签名哈希算法 |
指明证书签名所用的算法,需要放到证书里面,这样才能被证书签名保护 |
颁发者 | 包括了证书颁发者的身份信息,比如认证机构名称、域名和所在地等信息 |
有效期 | 包括开始日期和结束日期,在这段时间内证书是有效的 |
使用者 | 包含证书申请者的身份信息,包括申请者域名、组织名称、组织所在地等信息 |
公钥 公钥参数 |
包含了证书使用者的公钥、使用的签名算法,可选参数等信息,使用ECC比RSA有更短的公钥也即更小的通信量 |
仅制定证书的规范还不足以支持公钥的实际运用,我们还需要很多其它的规范,例如应该由谁来颁发可信的证书、如何颁发、私钥泄露时应该如何作废证书?到这一步,我们就已经踏入了社会学的领域,需要让公钥以及数字签名技术称为一种社会性的基础设施,即公钥基础设施(Public-Key Infrastructure),简称PKI。可以说,PKI 是为了能够更有效的运用公钥而制定的一系列规范的总称。PKI 主要由证书订阅人(申请并提供证书的服务端)、证书登记注册机构(RA: Registration Authority)、证书认证颁发机构(CA: Certification Authority)、证书使用者(请求验证证书的客户端)等部分构成,证书的申请与使用过程如下:
PKI 构成要素 | 功能描述 |
---|---|
订阅人 | 向注册登记机构申请证书,根据需要申请作废已注册的公钥 |
注册登记机构RA | 主要完成一些证书签发的相关管理工作,比如对用户进行必要的身份验证(域名验证、组织验证、扩展验证等)、找CA签发证书等 |
认证颁发机构CA | 会在确认申请用户的身份之后签发证书,同时CA会在线提供其所签发证书的最新吊销信息,方便客户端验证证书的有效性 |
使用证书的客户端 | 向服务端请求证书,使用本地(比如操作系统或浏览器中)保存的CA公钥验证来自服务端的证书签名,检测证书的吊销状态等有效性信息 |
当证书申请者出现私钥泄露或者不再使用证书等情况时,就需要将证书作废。要作废数字证书需要符合相应的标准或流程,目前主要有两种证书吊销标准:
- CRL(Certificate Revocation List):证书吊销列表CRL是一组未过期、但是却已经被吊销的证书序列号列表,CA维护了一个或多个这样的列表,每一张证书都需要在CRL分发点扩展字段中包含对应的CRL地址。CRL最大的问题在于它越来越大,实时查询起来会非常慢;
- OCSP(Online Certificate Status Protocol):在线证书状态协议OCSP允许验证证书的客户端获得一张证书的吊销信息,OCSP服务器的地址包含在证书的授权信息访问扩展字段中。OCSP支持实时查询并且解决了CRL最大的缺点,证书吊销检查更快速可靠,但也带来了一些新的问题,这些问题将在网络攻防中不断解决。
有了用于管理传递公钥的 PKI,也就解决了前一章提到的数字签名技术无法确认通信对端真实有效性的问题。网络攻防一直都存在,自然也少不了针对证书的攻击,比如攻击者可以在公钥注册认证前替换待认证的公钥,证书申请者可以在向CA认证机构提交公钥时,使用CA公钥加密后再发送给认证机构,同时认证机构也可以再次与申请者确认收到的公钥是否正确。还包括对认证机构本身的攻击,比如窃取认证机构的私钥就可以伪造证书,这主要就靠认证机构如何妥善保管升级自己的私钥了,对于已经泄露的私钥,及时对相关证书进行吊销处理,尽快减小损失。
2.2 TLS 1.2 握手过程
前面已经介绍了TLS 安全传输的所有技术,包括信息认证加密、共享密钥协商、通信双方身份认证等技术方案,接下来简单介绍TLS 协议的工作原理。前篇博文TLS 加密原理中已经介绍了,TLS 协议是由TLS 记录协议和TLS 握手协议这两层协议叠加而成的,位于底层的TLS 记录协议负责进行信息传输和认证加密,位于上层的TLS 握手协议则负责除加密以外的其它各种操作,比如密钥协商交换、身份认证等。TLS 记录协议的报文结构与工作原理已经在前篇博文中简单介绍过了,这里重点介绍TLS 握手协议。
TLS 握手协议可以分为四个子协议:
- 握手协议:负责在客户端和服务器之间协商决定密码算法和共享密钥,包括基于证书的认证操作;
- 密码规格变更协议:负责向通信对象传达变更密码方式的信号,在TLS 1.3版本中不再需要该协议;
- 警告协议:负责在发生错误时将错误传达给对方;
- 应用数据协议:将TLS 上面承载的应用数据传达给通信对象的协议。
TLS 握手过程也可以看到这四个子协议发挥作用的地方,警告协议只在发生错误异常时才发挥作用,所以正常的握手过程只看得到握手协议、密码规格变更协议、应用数据协议这三部分。TLS 1.3 版本进一步优化了整个握手过程,因为废弃了很多不安全的加密算法,仅支持5种安全高效的加密组件(TLS 1.2支持多达37个加密组件),精简的加密组合可以不再需要密码规格变更协议,减少了通信双方握手阶段的往返次数。
由于TLS 1.2 协议仍是目前主流,这里