HTTPS的加密原理

通过CA证书机构颁发的证书获取公钥**,进行非对称加密**,沟通和服务器交换客户端生成的秘钥。然后用客户端生成的秘钥与服务端进行对称加密通信。
对客户端生成的对称秘钥进行非对称加密,非对称加密的公钥来源于CA证书办法机构。
HTTPS的证书验证和客户端秘钥传输都是HTTPS握手时候完成的,是客户端自己处理,不需要开发介入
传送门: https://zhuanlan.zhihu.com/p/43789231

为什么需要加密?

因为http的内容是明文传输的,明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击。所以我们才需要对信息进行加密。

加密方式

对称加密

用同一个密钥,对信息同时可以进行加密和解密。算法耗时短。
如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。然而最大的问题就是这个密钥怎么让传输的双方知晓,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,那在这个传输过程中密钥被别人劫持到手了怎么办?之后他就能用密钥解开双方传输的任何内容了,所以这么做当然不行。
对称加密的方式有很多,主要有以下几种:

  1. AES(Advanced Encryption Standard):这是一种常用的对称加密方式,速度快,安全性高。
  2. DES(Data Encryption Standard):这是一种老牌的对称加密方式,速度慢,安全性已不够强。
  3. Blowfish:这是一种被广泛应用于加密软件和设备的对称加密方式,速度快,安全性较高。
  4. Twofish:这是一种用于替代AES的对称加密方式,速度快,安全性高。

这仅是一部分的对称加密方式,实际上还有很多其他的加密方式,但AES、DES和Blowfish是最常用的。

非对称加密

有两把密钥,通常一把叫做公钥、一把叫私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。算法耗时长。
同样还是需要保证交换秘钥这个过程,不会被第三方中间人获取到。
非对称加密方式有多种,主要有以下几种:

  1. RSA:这是最常用的非对称加密方式,它是一种数学方法,速度比较慢,但安全性高。
  2. Elliptic Curve Cryptography (ECC):这是一种快速的非对称加密方式,适用于加密资源有限的环境(如移动设备)。
  3. DSA(Digital Signature Algorithm):这是一种非对称加密方式,主要用于数字签名,保证数据在传输过程中不被篡改。
  4. Diffie-Hellman:这是一种用于密钥交换的非对称加密方式,它可以允许两个人在不安全的信道上交换密钥,从而实现安全的通信。

这仅是非对称加密方式的一部分,实际上还有很多其他的加密方式,但RSA和Diffie-Hellman是最常用的。

中间人攻击

如果在数据传输过程中,中间人劫持到了数据,此时他的确无法得到浏览器生成的密钥X,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开它,然而中间人却完全不需要拿到私钥A’就能干坏事了。请看:

  1. 某网站有用于非对称加密的公钥A、私钥A’。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)
  4. 浏览器生成一个用于对称加密的密钥X,用公钥B(浏览器无法得知公钥被替换了)加密后传给服务器。
  5. 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器
  6. 服务器拿到后用私钥A’解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人通过一套“狸猫换太子”的操作,掉包了服务器传来的公钥,进而得到了密钥X。**根本原因是浏览器无法确认收到的公钥是不是网站自己的,**因为公钥本身是明文传输的,难道还得对公钥的传输进行加密?

证明浏览器收到的公钥一定是该网站的公钥?

CA机构,它是如今互联网世界正常运作的前提,而CA机构颁发的“身份证”就是数字证书
网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明“该公钥对应该网站”。

证书本身的传输过程中,如何防止被篡改和替换?

数字签名的制作过程:

  1. CA机构拥有非对称加密的私钥和公钥。
  2. CA机构对证书明文数据T进行hash。

对hash后的值用私钥加密,得到数字签名S。(hash算法一方面是为了缩减加密前的长度,因为非对称加密耗时长。非对称加密可以加密的消息体长度有上限(public key length in bits / 8 - 11),否则会报错,所以必须先hash保证定长结果。)
明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。

浏览器验证过程:

  1. 拿到证书,得到明文T,签名S。
  2. 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
  3. 用证书里指明的hash算法对明文T进行hash得到T’。
  4. 显然通过以上步骤,T’应当等于S‘,除非明文或签名被篡改。所以此时比较S’是否等于T’,等于则表明证书可信。

怎么证明CA机构的公钥是可信的?

操作系统、浏览器本身会预装一些它们信任的根证书,如果其中会有CA机构的根证书,这样就可以拿到它对应的可信公钥了。
实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链或数字证书链。也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。
另外,不知你们是否遇到过网站访问不了、提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书(风险自己承担XD)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。

每次进行HTTPS请求时都必须在SSL/TLS层进行握手传输密钥吗?

服务器会为每个浏览器(或客户端软件)维护一个session ID,在TLS握手阶段传给浏览器,浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的session ID下,之后浏览器每次请求都会携带session ID,服务器会根据session ID找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了!


附录

TLS 握手示意
image.png