目录
HTTP
HTTP全程Hypertext Transfer Protocol,超文本传输协议,作为万维网初期的产物,影响十分巨大。但是HTTP自诞生以来就像存在一些不可避免的缺点,最大的问题就是"透明传输",所有的数据在网络上都是“裸奔”,这对于用户是十分致命的。而且存在中间人攻击,被窃听的风险。
HTTPS
为了解决HTTP存在的缺点,引入了HTTPS=HTTP+S,其中S代表SSL或者TLS加密协议。从传输层的角度来看,HTTPS在HTTP的TCP三次握手之后还有SSL/TLS四次握手,在之后的数据传输以及通信过程中,都会使用加密方式进行传输。S解决了三个问题:
- 加密传输数据:利用对称加密算法加密数据再进行传输
- 包校验:检验包的完整性,保证数据不会被篡改
- 身份验证:验证通信方的身份,保证不被中间人攻击
SSL/TLS四次握手
SSL四次握手的目的就是为了使用非对称加密"生成"之后对称加密所需要的密钥,分为四次握手环节:
- ClientHello:由客户端先发起,发送内容包含了一个随机数A,以及支持的加密算法版本,SSL/TLS套件的版本。
- ServerHello:服务端进行回应,对客户端的加密版本以及SSL套件进行选择确认,并生成第二个随机数B发给客户端,同时发送自己的数字证书和公钥。
- ClientKeyExchange:客户端使用公钥对数字证书进行确认,如果证书得到确认,那么拿出数字证书当中的服务器的公钥S,此时客户端再生成第三个随机数C,并使用公钥进行加密S(C),将S(C)传输给服务端。此时客户端拥有A,B,C三个随机数,将A,B,C作为对称加密算法的种子可以生成客户端的对称密钥。
- Finished:服务端接收到了S(C)之后使用自己的私钥进行解密得到随机数C。此时服务端也拿到了A,B,C三个随机数,此时同样使用A,B,C作为种子,生成对称密钥。
以上就是四次握手的基本过程。完成四次握手之后,双方就可以基于对称密钥进行加密通信,虽然四次握手的过程并不难理解。但是,其中许多的细节值得琢磨。
对称加密和非对称加密
对称加密算法在加密和解密阶段使用的秘钥是相同的,算法的保密性取决于双方对秘钥的保管,如果有一方泄露了秘钥,那么对称加密算法就会失效,必须更换秘钥。常见的对称加密算法有DES,3DES,AES等。其中3DES是指进行三次DES加密,表示为Y=DES_{K1}(DES_{K2}^{-1}(DES_{K1}(X))),3DES需要两个秘钥K1以及K2,首先使用K1对明文X进行加密,在使用K2进行解密,之后再使用K1进行加密。这里的K1,K2秘钥是通信双方都拥有的,除此之外没有第三方拥有,也就保证了HTTPS的加密属性,加密信息不被第三方所窃取。但是,对称秘钥在传输时的安全性却很难得到保障,因此非对称算法被提了出来。
与对称加密不同的是,非对称加密算法使用两组不同的秘钥,分别称为公钥/加密秘钥(Publish Key, PK)和私钥/解密秘钥(Secret Key, SK)。其中PK是公开的,任何人都可以获取,SK只能自己所有。此外加密算法(Encrypt, E)和解密算法(Deencrypt, D)是不同的算法,且都是公开的。假设明文为X,那么就有:$Y=E_{PK}(X)$以及$X=D_{SK}(E_{PK}(X))=E_{PK}(D_{SK}(X))$,最值得注意的就是,PK只能用于加密信息,无法解密使用SK加密的消息,也就是D_{PK}(E_{SK}(X)) != X。并且其中的D(X)并不是用于数据加密,因为公钥PK是人人可得的,也即人人都可以通过E(D(X))得到明文X,可以认为对明文解密的操作是"签名操作"。
据此可以看到,对称加密和非对称加密的主要不同在于,对称加密是使用对称密钥进行一对一双向保密通信,但是非对称加密则是使用多对一单向保密通信。同时,非对称加密对算力的要求也远大于对称加密。但是,即便是抛开算力不谈,HTTPS也无法完全使用非对称加密进行全程通信,毕竟非对称加密只是单向通信。然而使用非对称加密算法来传递对称密钥却是一个可行的办法。
数字签名
HTTPS的还一个重要特性就是能够鉴别数据包的完整性(校验数据没有被篡改过),以及进行身份验证(保证数据的来源是目标服务器)。数据签名可以满足前面两个特定,此外数字签名还具有不可否认的性质(也即不可否认之前发过消息)。
为了达到签名的目的,首先需要使用私钥SK对明文进行D运算,之后所有人都可以使用PK得到明文,也即E_{PK}(D_{SK}(X))=X,由于只有服务端A拥有私钥SK,因此只要经过简单的验证就可以得到报文的来源就是A,这就是报文鉴别的功能。上述过程虽然可以鉴别A的身份,但是报文X却是可以被获取到明文,因为所有人都可以获得PK。有无办法可以使得在签名的同时也加密X呢。答案是可以的,假设服务端的A的公钥和私钥分别为PKA,SKA,客户端的公钥和私钥分别为PKB,SKB,那么西安交换双方的公钥,也即A持有PKB,B持有PKA,如果此时A需要发送签名报文X,那么先由SKA进行运算得到D_{SKA}(X),之后再由PKB进行加密,可以得到E_{PKB}(D_{SKA}(X)),在第三方没有SKB的情况下是不可能对E_{PKB}(D_{SKA}(X))进行解密的。加密信息达到B之后,经过SKB的解密以及PKA的运算,可以得到X。使用单向或者双向认证可以达到服务端和客户端相互认证的目的。
鉴别
鉴别可以区分为报文鉴别和实体鉴别(身份鉴别)。之前提到的数字签名就可以达到鉴别的目的,但是对于报文较长的消息进行签名会需要较长的计算时间。退而求其次,可以使用散列函数来对报文进行鉴别,具体为:发送方使用散列函数H(如MD5)对X进行运算得到定长的摘要,最后传输的是(X, H(X))。接收方得到(X^{'}, H(X)^{'})之后对X进行运算,如果H(X)^{'}=H(X^{'})那么可以证明报文的完整性。但是,这样的操作依然不安全,因为H是大家都指导的,所以想要仿造(X, H(x))是很简单的。解决办法就是对H(X)进行加密,即便有第三方对X进行篡改,但是也无法生成加密之后的H(X)。据此引入了MAC(Message Authentication Code, 报文鉴别码),使用对称算法对H(X)进行加密,之后鉴别的时候再进行解密。此时也需要对称密钥得到安全的传输。
数字证书
虽然数字签名能够起到身份证明的作用,但是理论上谁都与可以制作签名,这也就造成了不安全性。例如任何人都可以制作一个私钥以及公钥,并声明"I am Google",并且还能够使用公钥进行验证。很显然这样的签名是及其不安全的,由此引出了数字证书的概念。