本文不讨论为什么要使用https,本文探讨的核心问题是,https是如何实现安全的通信。
要解决的问题
现在假设有两个端,分别是Alice和Bob,我们分别简称A与B,A与B如果需要实现安全的通信,我认为至少要解决两个问题:
- A必须能够确认,与A正在通信的是B,当出现网络劫持的现象,与A通信的不是B,而实际是C。因此必须解决B的身份认证的问题。
- A和B的通信如果被监听,则内容必须加密。必须解决如何共享密钥的问题。
HTTPS的解决方案
- A向B发送请求,告知B,A支持的tls版本,支持的压缩算法、加密算法,以及随机数a[Client Hello]
- B告之A,B所采用的tls版本,压缩算法、加密算法,以及随机数b[Server Hello]
- B向A发送证书,并告之A信息已传输完成[Certificate、Server key exchange、Server Hello Done]
- A校验通过后,生成随机数pre-master,发送给B,用证书中的公钥加密,A和B通过a、b、pre-master各自生成密钥key[client key exchange]。A使用key加密,发送给B,握手。[EnArypted Handshake Message]
- B使用key加密,发送给A,握手。[EnArypted Handshake Message]
- 握手成功后,使用key加密通信。
HTTPS如何解决问题的
问题1---B的身份认证
想象一下我们生活中的例子,你去住酒店,说自己是守法公民,前台的小姐姐肯定不信你,一定会让你出示身份证,再通过身份证校验器和图象识别等技术来验证你的身份,这个环节,实际上就是国家在为你做证明。同样,如何对A证明B就是B,我们就需要权威机构为B作证,也就是第2步中证书的概念。
我先解释下证书的概念,证书就相当于B的凭证,可以理解成一个文件,里面包含有它的所有者(B的域名),证书的发证机构和证书的有效期。而签名的实质就是对证书做hash运算,再用CA的私钥加密。A请求到证书后(第4步),用公钥解密签名,再用相同的Hash算法对证书做hash运算,如果解密后的值和hash运算得到的值相等,则证书校验通过。(注:A不会相信B的证书,除非A根据证书的颁发者,层层溯源,直到ROOT CA[可以理解为最权威的机构],再根据ROOT CA的公钥,层层解密签名。)
证书的校验
- 获取B的证书;
- 拆分证书获取“元数据”和“加密的签名”;
- 根据“元数据”层层溯源证书,直到root CA,否则,该证书不可信;
- 回溯证书,用“元数据”中的公钥解密层层机密“加密的签名”,得到Hash
- 用同样的Hash算法获取“元数据”的Hash值;
- 比较第3步和第4步获取的Hash值,相等则通过校验;
至此,HTTPS已经解决了身份认证的问题,但我还想再想补充一下一点思考:
- A:是否应该采用双端认证?Q:对于普通用户来说,我觉得没有必有,因为毕竟要弄CA证书,需要一笔成本;但是对于企业与企业之间的通信,还是可以考虑的
- A:为什么要弄一些中间证书,直接ROOT CA不好吗?多层级的证书结构可以保证信息的安全,如果直接由ROOT CA在线签发证书,风险太大。中间证书在线签发,根证书线下签发,可以保证证书的安全性。
问题2---报文加密
- A、B在通信时候,通过在第3步的时候,交换公开质数g,p;
- A计算 Pre-master = (g^a) mod p [注:^是平方根,不是异或],并将该值发送给B;
- B计算 Pre-master = (g^b) mod p;
- A、B各自计算共同的密钥 KEY = (g^a^b) mid p,之后用R通信;
- 各自用KEY通信握手[EnArypted HandShake Message]
根据离散对数原理,当使用非常大的a, b 以及 p[质数]时,仅仅通过 g,p,(g^a) mod p,(g^b) mod p是无法计算KEY的。具体的算法可以参考 zh.wikipedia.org/wiki/%E8%BF…
抓包实战
- Client Hello。见上文HTTPS的解决方案第1步;
- Server Hello。见上文HTTPS的解决方案第2步;
- Certificate,Server key exchange、Server Hello Done。见上文HTTPS的解决方案第3步,服务器除了传递证书外,还告诉客户端密钥交换算法所需的参数;
- 见上文HTTPS的解决方案第4步。根据步骤3传递的S端密钥交换算法参数,以及自身C端的密钥交换算法参数,计算出公钥,并用公钥加密报文,尝试握手;
- 见上文HTTPS的解决方案第5步。S端根据C端传递的密钥交换算法参数,得到公钥,尝试握手。同事要求客户端用New Session Ticket(已经协商好的对称密钥)保存会话的相关信息,New Session Ticket是用只有S端才能解密的的公钥加密的。下次通信过程中,服务端如果可以根据New Session Ticket成功解密,就可以迅速握手。
总结
至此,安全通信的两个问题解决了。但我想提出一个问题,在问题1解决的前提下,是否可以通过A的公钥加密 一个随机生成的KEY 来做为对称密钥?