加密的⽅式有很多,但是整体可以分成两⼤类:对称加密和⾮对称加密。
1.3.1 方案一:只使用对称加密
如果通信双⽅都各⾃持有同⼀个密钥X,且没有别⼈知道,这两⽅的通信安全当然是可以被保证的(除⾮密钥被破解)
引⼊对称加密之后,即使数据被截获,由于⿊客不知道密钥是啥,因此就⽆法进⾏解密,也就不知道请求的真实内容是啥了。
但事情没这么简单,服务器同⼀时刻其实是给很多客户端提供服务的,这么多客户端,每个⼈⽤的秘钥都必须是不同的(如果是相同那密钥就太容易扩散了,⿊客就也能拿到了),因此服务器就需要维护每个客户端和每个密钥之间的关联关系,这也是个很⿇烦的事情~
⽐较理想的做法就是能在客⼾端和服务器建⽴连接的时候,双方协商确定这次的密钥是啥。
但是如果直接把密钥明⽂传输,那么⿊客也就能获得密钥了~~此时后续的加密操作就形同虚设了。
因此密钥的传输也必须加密传输!
但是要想对密钥进⾏对称加密,就仍然需要先协商确定⼀个"密钥的密钥",这就成了"先有鸡还是先有蛋"的问题了,此时密钥的传输再⽤对称加密就行不通了。
1.3.2 方案二:只使用非对称加密
鉴于⾮对称加密的机制,如果服务器先把公钥以明⽂⽅式传输给浏览器,之后浏览器向服务器传数据前都先⽤这个公钥加密好再传,从客户端到服务器信道似乎是安全的(有安全问题),因为只有服务器有相应的私钥能解开公钥加密的数据。
但是服务器到浏览器的这条路怎么保障安全?
如果服务器⽤它的私钥加密数据传给浏览器,那么浏览器⽤公钥可以解密它,⽽这个公钥是⼀开始通过明⽂传输给浏览器的,若这个公钥被中间⼈劫持到了,那他也能⽤该公钥解密服务器传来的信息了。
1.3.3 方案三:双方都使用非对称加密
- 服务端拥有公钥S与对应的私钥S’,客户端拥有公钥C与对应的私钥C’
- 客户和服务端交换公钥
- 客户端给服务端发信息:先⽤S对数据加密,再发送,只能由服务器解密,因为只有服务器有私钥S’
- 服务端给客户端发信息:先⽤C对数据加密,再发送,只能由客户端解密,因为只有客户端有私钥C’
这样貌似也⾏啊,但是:
• 效率太低。
• 依旧有安全问题
1.3.4 方案四:使用对称加密+非对称加密
先解决效率问题:
• 服务端具有⾮对称公钥S和私钥S’
• 客户端发起https请求,获取服务端公钥S
• 客户端在本地⽣成对称密钥C,通过公钥S加密,发送给服器.
• 由于中间的⽹络设备没有私钥,即使截获了数据,也⽆法还原出内部的原⽂,也就⽆法获取到对称密钥(真的吗?)
• 服务器通过私钥S’解密,还原出客户端发送的对称密钥C.并且使⽤这个对称密钥加密给客户端返回的响应数据。
后续客户端和服务器的通信都只⽤对称加密即可.由于该密钥只有客户端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义。
由