开始正文之前先说一下相关概念:
数字签名
数字签名就是“非对称加密+摘要算法”,其目的不是为了加密,而是用来防止他人篡改数据。
CA
Certificate Authority,即颁发数字证书的机构。是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。
摘要算法
即是hash算法,采用hash函数生成证书元数据的摘要。摘要算法不是用来加密的,其输出长度固定,相当于计算数据的指纹,主要用来做数据校验,验证数据的完整性和正确性。常见的算法有CRC、MD5、SHA1、SHA256。
本文从以下几个方面介绍数字签名、加密通信过程:
- CA机构自签名及对下属子CA进行签名
- 服务器、客户端生成各自的数字签名证书
- TLS握手
CA机构自签名及对下属子CA进行签名
CA机构一般分为根CA和子CA,根证书通过自己自签名完成证书发放,子CA向根CA申请签名,得到证书。通过子CA对服务器申请文件进行数字签名,进而形成证书链。
签发证书的过程:
- 1.撰写证书元数据:包括 签发人(Issuer)、地址、签发时间、有效期 等,还包括证书持有者(Owner)基本信息,比如 DN(DNS Name,即证书生效的域名)、 Owner 公钥 等信息
- 2.使用通用的 Hash 算法(如SHA-256)对证书元数据计算生成 数字摘要
使用 Issuer 的私钥对该数字摘要进行加密,生成一个加密的数字摘要,也就是Issuer的 数字签名 - 3.将数字签名附加到数字证书上,变成一个 签过名的数字证书
将签过名的数字证书与 Issuer 的公钥,一同发给证书使用者(注意,将公钥主动发给使用者是一个形象的说法,只是为了表达使用者最终获取到了 Issuer 的公钥)
服务器、客户端生成各自的数字签名证书
服务器和客户端向CA机构发送申请证书文件,得到各自的证书。
数字证书签发过程和上面叙述类似。
TLS握手
- 1.ClientHello
client->server:
hello,咱建立个连接呗,我这边的支持的最高版本是TLS1.1,
支持的密码套件(cipher suite)有“TLS_RSA_WITH_AES_128_CBC_SHA”和“TLS_RSA_WITH_AES_256_CBC_SHA256”,
支持的压缩算法有DEFLATE,我这边生成的随机串是abc123456。
密码套件就是一个密码算法三件套,里面包含了一个非对称加密算法,一个对称加密算法,以及一个数据摘要算法。以TLS_RSA_WITH_AES_128_CBC_SHA为例,RSA是非对称加密算法,表示后面用到的证书里面的公钥用的是RSA算法,通信的过程中需要签名的地方也用这个算法,并且密码(key)的交换过程也使用这个算法;AES_128_CBC是对称加密算法,用来加密握手后传输的数据,其密码由RSA负责协商生成;SHA是数据摘要算法,表示后面交换的证书里签名
用到的摘要算法是sha1,并且后续通信过程中需要用到数据校验的地方也是用的这个算法。在Record Protocol协议中,摘要算法是必须的,即数据包都需要有校验码,而签名是可选的。
- 2.ServerHello
server收到client的hello消息后,就在自己加载的证书中去找一个和客户支持的算法套件相匹配的证书,并且挑选一个自己也支持的对称加密算法(证书里面只有非对称加密和摘要算法,不包含对称加密算法)。如果出现下面几种情况,握手失败:
客户端支持的TLS版本太低,比如server要求最低版本为1.2,而客户端支持的最高版本是1.1
根据客户端所支持的密码套件,找不到相应要求的证书
无法就支持的对称加密算法达成一致
如果一切都成功,发送
server->client:
hello,没问题,我们就使用TLS1.1吧,
算法采用“TLS_RSA_WITH_AES_256_CBC_SHA256”,压缩我这边不支持,我这边生成的随机数是654321def。
-
3.Certificate
发送服务器证书 -
4.CertificateRequest
要求客户端发送证书 -
5.ClientKeyExchange
用服务器的公钥加密生成的随机值 -
6.服务器通过之前协商的对称加密算法将随机值生成对称密码,用于之后的通信加密
验证过程:
当服务器发送自己的证书给客户端时,客户端通过解压得到证书元数据和摘要,通过协商好的摘要算法计算元数据摘要,在通过与CA机构的公钥解密发送过来的摘要进行对比,若是相同,则证明是真实的服务器,若不是,则是冒充。
在未协商出对称密码之前通信都是使用对方的公钥加密。