目录
4.client_key_exchange+change_cipher_spec+encrypted_handshake_message(客户端->服务器)
5.change_cipher_spec+encrypted_handshake_message(服务器->客户端)
一、https是什么
https = http + SSL/TLS 。即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。
http协议存在的问题是:HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,“裸奔”在互联网上,所以很容易遭到黑客的攻击。
客户端发出的请求很容易被黑客截获,如果此时黑客冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉,所以我们经常会听到一词“劫持”,现象如下:
下面两图中,浏览器中填入的是相同的URL,左边是正确响应,而右边则是被劫持后的响应
所以 HTTP 传输面临的风险有:
(1) 窃听风险:黑客可以获知通信内容。
(2) 篡改风险:黑客可以修改通信内容。
(3) 冒充风险:黑客可以冒充他人身份参与通信。
因此https就应运而生,https可以把http传输的信息进行加密后再发送,这样的话,即使黑客能截获到报文,也破译不了里面的内容。
二、https的加密原理
加密信息一般有两种类型:对称加密和非对称加密。
2.1 对称加密
对称加密的意思是,客户端和服务器双方拥有着相同的密钥,即客户端和服务器收到的报文都是用同一个密钥进行加密解密的。
优点:对称加解密具有速度快,性能高的特点。
缺点:对称加密 需要客户端和服务器都拥有同一个密钥,那么怎么能让双方都有相同的密钥呢?如果通过一方把密钥直接发给另一方,那么这发送的过程肯定是没加密的,那么就很有可能被人截获。而且客户端和服务器数量多的话,双方都要维护很多的密钥。
2.2 非对称加密
非对称加密,是客户端有一个公钥(公开的密钥),这个公钥是所有人都可以知道,公开的。而服务器则有一个私钥,这个私钥则是只有服务器自己知道。
客户端用公钥进行加密/解密,然后把密文传给服务器,然后服务器用私钥进行解密/加密。公钥加密的密文只有私钥可以解密,私钥加密的内容,也只有公钥可以解密。
优点:不需要维护过多的密钥。安全性高。
缺点:公钥是公开的(也就是黑客也会有公钥),所以第 ④ 步私钥加密的信息,如果被黑客截获,其可以使用公钥进行解密,获取其中的内容。而且效率低。
2.3 对称加密+非对称加密(https的加密方式)
既然 对称加密 和 非对称加密 都各有缺陷,那么就把两者合在一起,取其精华,去其糟粕。
即总体过程是:(先非对称加密,后对称加密)
1. 一开始,服务器保管好私钥。
2. 服务器发送对应的公钥给其他客户端。(该公钥用于解密/加密 私钥的信息)
3. 然后 客户端 只要把 对称加密 的密钥通过 得到的公钥 加密,再发送给服务器。服务器通过私钥 解密 后,就也能得到 对称加密 的密钥。
4. 然后 客户端 和 服务器就可以通过 对称加密 方式的密钥进行通话了。
但是问题又来了,服务器怎么把 公钥 发送给客户端呢?如果直接发的话,也会存在被黑客(中间人)调包的可能性。
数字证书(解决公钥传输的信任问题)
服务器向客户端并非直接传送公钥,而是传的是一个证书。这个证书由第三方权威机构(Certificate Authority,简称 CA)颁发。
服务器可以向CA申请证书,然后在证书上附上自己的公钥。申请证书时,必须提交DNS 主机名等信息,CA 会根据这些信息生成证书。
有权威机构背书的证书做担保,就能相信所传输的公钥。
但是仍有两个问题:
1. 如何验证证书的真实性
证书上会有个 数字签名,数字签名 可以用于防止证书造假。那么 数字签名是怎么产生的呢?
步骤:
用摘要算法(如MD5)将 证书明文 (如证书序列号,DNS主机名等)生成摘要,然后用第三方权威机构的私钥进行加密(签名)。
换句话说,如上图,证书的签名是由证书的其他内容信息生成的摘要加密而成的。
为什么要生成摘要后再加密,而不是直接加密呢?
因为使用非对称加密是非常耗时的,如果把整个证书都加密生成签名的话,客户端验证签名也要把签名解密,证书明文较长,所以客户端验签的时间也会比较长,而用摘要的话,验签过程就会快很多。
客户端验签过程(验签=验证数字签名)
服务器把证书发给客户端后,客户端的验签过程如下:
客户端拿到证书后,就拿到了 证书明文 和 签名。这时候,一方面对签名进行公钥解密,得到摘到A。
另一方面,对证书明文 进行摘要算法,提取摘要,得到摘要B。
然后比对摘要A和摘要B。如果摘要A=摘要B,那么就证明 证书明文 和签名是对的上的,意味着,证书明文没有被 中间人(黑客) 改动过。那就证明 证书明文上附带的公钥也是没有被改变过的。
为什么证书明文生成的摘要还要用 第三方私钥进行加密?
假设,我们不用第三方私钥进行加密的情况: 签名 = 用摘要算法(MD5等) 处理证书明文 。由于摘要算法是公开的,所以所有人(包括中间人)都能知道摘要算法。 所以如果中间人要修改证书,他会首先把 证书明文 进行修改,然后 把修改过的证书明文 用摘要算法生成摘要,然后把签名处直接替换成 修改过明文生成的摘要。这就可以瞒天过海了。
当如果我们加入第三方私钥来对摘要进行加密:那么签名=用摘要算法生成摘要+第三方私钥加密。由于私钥是不公开的,只有第三方权威机构有,所以中间人即使修改了证书明文,并生成了摘要,也无法替换掉证书上原有的签名,因为中间人无法获取私钥。如果强行修改,那么当客户端用第三方公钥对签名进行加密时,那在摘要对比的环节上肯定不成功,就会判断证书非法。
CA公钥如何安全地传输到客户端
其实还是会有疑惑的地方,就是第三方权威机构CA的公钥要怎么传输给客户端,要是先直接通过服务器传过来,那不也是裸奔吗?同样也会出现被中间人替换掉第三方公钥的情况。
如果中间人截获了第三方公钥,并替换成自己的公钥,那么中间人就完全可以冒充服务器跟客户端通信了,这是十分不安全的。
答案是,第三方权威机构CA的公钥其实是内置在操作系统的 Root CA证书上的,无需传输。
服务器传输 CA 颁发的证书,客户中收到证书后使用内置 CA 证书中的公钥来解密签名,验签即可,这样的话就解决了公钥传输过程中被调包的风险。
2. 如果防止证书被调包
实际上任何人都可以向CA申请证书,中间人也不例外。
那有没有可能,中间人截取了服务器发给客户端的证书(里面装有真公钥),然后中间人把服务器发送给客户端的证书给调包,中间人获得服务器的真公钥,然后把中间人自己伪造的证书发给客户端,然乎客户端使用内置在操作系统的CA 对中间人发来的证书进行验签,由于中间人的证书也是从CA处申请的,所以验签会通过,只是客户但验签通过后拿到的是中间人伪造的假公钥而已。那么客户端用假公钥对通信使用的 对称密钥 进行加密,本想着把对称密钥发给服务器后,就能跟服务器进行加密通信了,但由于加密的公钥是中间人的假公钥,所以在把对称密钥发送给服务器的途中,中间人截获后,可以对携带的对称密钥进行解密,所以中间人是可以获得 对称密钥的,然后中间人再用服务器的真公钥加密,再发给服务器,那么就可以在客户端和服务器都不知情的情况下,监听双方的通信内容。
答案是: 不会存在这种情况的。
因为客户端除了通过验签方法验证证书的合法性外,还需要验证证书上的域名是否和自己请求的域名一致,中间人虽然可以向CA申请证书,但如果此证书的域名和客户端请求的域名不一致,客户端也会认定为不通过。
三、https的握手过程
逐个步骤分析:
1.client hello
客户端发起请求,以明文传输请求信息。包括 版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等,详细如下:
- 支持的最高TSL协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本不再使用低于 TLSv1 的版本;
- 客户端支持的加密套件 cipher suites 列表, 每个加密套件对应前面 TLS 原理中的四个功能的组合:认证算法 Au (身份验证)、密钥交换算法 KeyExchange(密钥协商)、对称加密算法 Enc (信息加密)和信息摘要 Mac(完整性校验);
- 支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
- 随机数 random_C,用于后续的密钥的生成;发送给服务器
- 扩展字段 extensions,支持协议与算法的相关参数以及其它辅助信息等,常见的 SNI 就属于扩展字段,后续单独讨论该字段作用。
2.server hello
服务器返回协商的结果,包括选用的协议版本号version,选用的加密套件 cipher suite,选用的压缩算法 compression method,生成另一个随机数 random_S(用于后续密钥的生成)并发送给客户端
3.证书校验
客户端验证证书的合法性,如果验证通过,才会进行后续通信,合法性验证包括如下:
- [证书链]的可信性 trusted certificate path
- 证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不同的客户端行为会不同;
- 有效期 expiry date,证书是否在有效时间范围;
- 域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;
4.client_key_exchange+change_cipher_spec+encrypted_handshake_message(客户端->服务器)
client_key_exchange
证书合法性验证通过后,客户端计算产生随机数字Pre-master,并用证书的公钥加密,发送给服务器。
并且此时的客户端是已经具有计算 协商密钥(即对称加密的密钥) 的所有条件:两个明文随机数 random_C 和 random_S 与自己计算产生的 Pre-master,计算得到协商密钥:
enc_key=Fuc(random_C, random_S, Pre-Master)
change_cipher_spec
客户端通知服务器后续的通信都采用 协商的密钥(对称加密的密钥) 进行加密通信
encrypted_handshake_message
客户端结合之前所有通信参数的 hash 值与其它相关信息生成一段数据,采用 协商密钥 进行加密,然后发送给服务器用于数据的握手与验证
5.change_cipher_spec+encrypted_handshake_message(服务器->客户端)
服务器用私钥解密加密了的Pre-master数字,基于之前交换的两个明文随机数 random_C 和 random_S,计算得到协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
change_cipher_spec
验证通过之后,服务器同样发送 change_cipher_spec 以告知客户端后续的通信都采用协商的密钥与算法进行加密通信;
encrypted_handshake_message
服务器也结合所有当前的通信参数信息生成一段数据并采用协商密钥与算法加密并发送到客户端;
6.握手结束
客户端计算所有接收信息的 hash 值,并采用协商密钥解密 encrypted_handshake_message,验证服务器发送的数据和密钥,验证通过则握手完成;然后接下来的通信都是以 协商密钥(对称加密的密钥)进行加密通信的
四、http和https的区别
- HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TLS协议进行了加密处理。
- http和https使用连接方式不同,默认端口也不一样,http是80,https是443。