-- TOC --
HTTPS就是安全的HTTP协议,所有数据都是通过加密的方式传输,安全可靠。本文介绍其实现原理。
HTTPS提供的安全通信,应用了对称加密,非对称加密,数据签名等技术。
在HTTPS的正常通信过程中,采用的对称加密,速度快,但是问题是客户端(就是指浏览器,以下同略)和服务器(网站服务器,以下同略)需要协商加密算法和秘钥,因为加密算法和秘钥要相同,才能正常使用对称加密。
这个协商的过程,就要用到非对称加密算法。服务器拥有私钥,客户端拥有公钥,于是相互直接都能解开协商过程的数据包。
但是,以上过程还是不够安全,如果遇到中间人攻击(MAN-IN-MIDDLE),客户端是无法判断其收到的服务器的公钥,是否真的就是真正的那个服务器发出来的。
因此,CA机构登场,CA的作用是给网站服务器制作数字证书(可以理解为一个特别的文件)。CA机构给网站颁发数字证书文件后,客户端其实获取到的是服务器的CA证书。这个证书里面包含的服务器的公钥,并且能够证明这是真的服务器的公钥。
这里有几个重要细节要梳理:
1, CA机构是行政发牌照,这一个环节是非技术因数;
2, CA机构发布的数字证书,其实就是用CA机构的私钥对服务器的公钥进行加密,客户端要使用CA机构的公钥来解密,获取服务器的公钥;由于第1点,一般浏览器或操作系统都已经存储了多家认证的CA机构的公钥,所以客户端在本地就可以直接使用CA的公钥解密;
3, 数字证书里面除了含有加了密的服务器的公钥之外,还有此证书本身验证真伪的必要信息,最重要的,是数字证书的签名;这个签名是一个信息摘要HASH(比如SHA),然后用CA机构的私钥加密;客户端要先用CA的公钥解密,然后使用收到证书中约定的方式,计算HASH值,然后对比,如果一致,表示证书是真的;
4, CA数字证书是不可篡改的,因为HASH值使用了CA机构的私钥加密,就算有中间人攻击,中间人可以解开并查看证书里面的所有信息,但是却无法修改这个证书,因为中间人没有CA机构的私钥;中间人如果用自己的私钥篡改证书数据,客户端是解不开的;中间人用CA机构的公钥篡改数据,客户端同样无法解开;中间人如果直接使用相同CA机构给它发的其它证书来代替,数字签名验证不会成功,因为中间人无法用CA机构的私钥来对不同的内容做加密;(用CA的公钥,只能解开CA私钥加密的数据;任何不使用CA私钥加密的数据,浏览器中的公钥都解不开)
5, 客户端拿到服务器的公钥之后,将对称加密的秘钥加密后,发给服务器,中间人无法用相同服务器的公钥来解密,所以看不到对称加密的秘钥;中间人如果篡改数据,效果相当于中间人成了另一个客户端;服务器在确定了对称加密的秘钥之后,使用其对信息进行加密,然后传输给客户端,双方正常加密通信,中间人毫无办法。
以上第4和5是理解整个过程安全性的关键点。
破解HTTPS的加密,关键点是2。如果系统中受信任的CA签发机构,来自不受信任的环节。例如:公司为了监控员工的上网行为,强行要求在系统中安装公司指定的软件,这时很可能有公司自签名的机构公钥被安装到系统中,并且被设置为受信任的CA机构,然后部分HTTPS流量,就可以在公司的某个网关上被解析,然后再打包发出去,收到的回应也是先解开,然后重新解密再发回,man in the middle。有人说,在这种系统中,用虚拟机上网,就可以发现问题。
整个HTTPS的流程,可以用下图来理解:
关键点就是那个CA证书,让客户端获取到了真实的服务器公钥,然后用这个公钥来加密协商后面的秘钥。整个HTTPS流程的安全关键在于CA机构,这个是政府认证的,另外就是私钥的安全,不能被窃取。
证书链(信任链)
证书里存放这公钥,此公钥用来验证另一个证书中的签名,然后拿到另一个公钥...
有一些网站的CA证书并不是CA机构的根证书签发,而是根证书下面的子根证书。
比如: CA_Root ---> CA_A ---> CA_A01 ---> 签发的网站证书WA
假如系统中有预存了CA_Root,当访问网站时,拿到证书WA,此时CA_Root中的公钥不能用来验证WA。然后,系统会根据WA证书的签发者,去获取此签发这的证书CA_A01。然后,发现还不能验证WA,继续去获取CA_A。现在,系统中的CA_Root中的公钥,可以验证CA_A,然后用CA_A的公钥验证CA_A01,最后用CA_A01的公钥验证WA。(通常Server会将此链条上的证书一次性发给Client,见下,这样delay会比较低,是合理的)
这条信任链建立在数字签名基础上。《三体》中说的猜疑链,因为宇宙中存在技术爆炸的可能。
不直接使用CA_Root签发证书的原因,是为了保护根证书。
根据TLS1.2协议规范,在ServerHello之后,Server向Client发送自己的证书,X509格式
,使用ASN.1 DER编码
。通常服务器会返回多个证书,因为当前域名往往不是由根证书直接签名的,而是使用由于根证书所签名的次级证书去签发具体域名的证书。
如果使用了多级证书,那么返回的证书列表中第一个必须是对应域名的证书,而后每个证书都是前一个证书的issuer,且最后一个证书是由系统中某个根证书签发的,注意根证书本身并不会一起返回。
使用openssl查看bing.com返回的证书链
:
OpenSSL> s_client -connect bing.com:443
CONNECTED(00000003)
depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = Microsoft Corporation, CN = Microsoft RSA TLS CA 01
verify return:1
depth=0 CN = www.bing.com
verify return:1
---
Certificate chain
0 s:CN = www.bing.com
i:C = US, O = Microsoft Corporation, CN = Microsoft RSA TLS CA 01
1 s:C = US, O = Microsoft Corporation, CN = Microsoft RSA TLS CA 01
i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
---
Server certificate
-----BEGIN CERTIFICATE-----
...
Certificate chain里面显示有2个证书。
HTTP协议演进
一张好图,感谢小林同学(https://xiaolincoding.com)他的网站我认为对任何层次的技术人员,都很有价值。
从HTTP/2开始,对TLS的支持就写入了标准。
最右边的图是不是有问题?难道TLS1.3+可以跑在UDP上?
私钥和公钥,不同的作用
用公钥加密,是为了向私钥拥有者传递加密信息,任何第三方都看不到;
用私钥(对内容Hash值)加密,是为了证明信息是由私钥拥有者发出的,同时证明信息没有被篡改。
本文链接:https://cs.pynote.net/net/202203292/
-- EOF --
-- MORE --