为什么需要加密?
因为http的内容是明文传输的,传输过程有可能被劫持或被篡改(中间人攻击),如何解决?
当然是加密。最简单的方式就是对称加密(快)。
对称机密就是一个密钥,可以理解为一把钥匙,我们使用它来加锁和解锁。加密和解密都使用同一个密钥。
但是,密钥要是泄漏了怎么办?就像是钥匙被人拿到了,可以随时开锁(解密)。
我们无法保证传输过程中既让密钥给双方,又不被泄漏,一旦泄漏就跟明文传输一样了。
有人会说:那双方约定好密钥,客户端预存好密钥就行了。
但是,这样是很不实际的,麻烦暂不说。如果有n个客户端,每个客户端都要保存,终究还是无法保证密钥的安全性。
这时就需要非对称加密登场了。
非对称加密一个密钥不够安全,那就用一对(公钥和私钥)。
通常的基本思路是客户端先向服务器端索要公钥,然后用公钥加密信息 (公钥加密法),服务器收到密文后,用自己的私钥解密。
但是问题又来了,最开始客户端索要公钥这一步,传输过程公钥也有可能被获取或者篡改,从而导致内容泄漏,所以信息还是存在安全问题。
非对称加密v2为了解决非对称加密公钥传输可能被篡改至信息泄漏的问题,那使用两对锁怎么样?
假设:
1. 服务器和客户端各自拥有一对公钥和私钥。
2. 双方明文交换公钥。
3. 通讯内容使用对方的公钥来加密,然后用自己的私钥解密。
这样”貌似“没问题,因为私钥都保持在各自手里,即使得到公钥也无法解密信息。
但公钥加密计算量大,很消耗时间,能否对称加密和非对称加密两者结合?
两者结合我们来改善一下:
1. 服务端拥有一对非对称加密密钥(公钥和私钥)。
2. 客户端向服务端索要公钥,服务端返回公钥。
3. 客户端生成一个对称密钥X,然后使用公钥加密X后,发给服务端。
4. 服务端用自己的私钥解密得到密钥X。
5. 之后数据都用密钥X来加密解密。
这就是https采用的加密方案(非对称加密和对称加密结合)。
但这个还是有漏洞,那就是中间人攻击。
中间人攻击什么是中间人攻击? 下图展示了中间人攻击的大致流程:
因此就引发了一个问题: 如何保证公钥不被篡改?
答案是将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
证书中心证书中心(certificate authority,简称CA),同样拥有非对称密钥(公钥和私钥)。
相对于一个具备权威的机构,是被公认的,可以用来颁发数字签名和数字证书。
这里涉及到"数字签名"(digital signature)和"数字证书"(digital certificate)。
数字签名,可以用来验证对方的身份信息,以下是数字签名大致生成过程:
数字证书
数字证书由用户+证书信息+数字签名构成(由CA颁发的同时包含CA公钥)。
那么有什么用呢?
我们还是已前面的“两者结合”例子来说明,证书身份验证过程:
1. 服务端拥有一对非对称加密密钥(公钥和私钥)。
2. 客户端向服务端索要公钥,服务端返回公钥。
3. 客户端生成一个对称密钥X,然后使用公钥加密X后,发给服务端。
4. 服务端用自己的私钥解密得到密钥X。
5. 之后数据都用密钥X来加密解密。
假设此时服务端申请到数字证书了
1. 客户端向服务端索要公钥,服务端返回公钥(附上数字证书)。
2. 客户端收到数字证书后,读取证书办发机构的公钥,然后从系统受信任证书机构列表查找,如果不存在,说明该服务端发过来的证书是不受信任的。
3. 客户端接着从数字证书取出CA公钥,解密得到:数字签名和服务端信息。
4. 客户端用证书中指定的加密算法对服务端信息进行hash加密。
5. 加密后的结果和证书解密出来的数字签名一致,说明身份可靠,也就是说证书里的公钥是安全的。
6. 接下来客户端就可以安心用该公钥加密密钥进行后面的通信了。
7. 如果签名不匹配,那就握手失败。
有人会说,那如果篡改或掉包证书呢?
其实证书假设被劫持了,但他没有CA私钥也是解不开里面数字签名的,即使被掉包,校验时发现签名不一致,那么就说明证书不是安全可靠的了。