知了堂|HTTPS协议的作用和原理

189 阅读6分钟

简单无加密的传输

网络时代,我们的所有通信都会经过网络进行传输,一个最简单的传输过程为:

A --> B (A对B说,B你好)

A <-- B (B回复A,A你也好啊)

这个简单的传输会途径互联网中的各种硬件设备,传输的过程是难以控制的,传输的内容也很容易在某个环节被窃听和篡改。

假设C是一个怀有恶意的中间人,在现实中,C可能是运行于某个路由器的恶意程序,那么,A发送给B的信息在途径C的路由器时,会被C窃听,也可能被C篡改:

A --> C --> B (A对B说,B你好,在B收到消息前,C先收到消息,将内容篡改为“B你真是个傻瓜”后,再发给B,这样A发送的原文就被篡改了,篡改后的内容,其实并不是A想发送给B的)

为了防止被C窃听和篡改我们的通信,需要引入加密层,也就是我们马上要开始讨论的HTTPS!

HTTPS基础——对称加密和非对称加密

在讨论HTTPS前,必须要了解两种加密算法,AES和RSA。

对称加密AES

对称加密就像是把信息装进一个盒子,然后加上一把锁,这把锁就是密钥,只有知道这把密钥,才能将加密后的内容解密得到原文。对称加密具体算法有很多种,比较常用的是AES,我们用AES来举例。

你好 -- AES加密 --> C4HU/E5dCxuF/hc7sflZWg (我们使用密钥k4ybj对原文“你好”进行了加密)

C4HU/E5dCxuF/hc7sflZWg -- AES解密 --> 你好 (我们使用密钥k4ybj对加密内容进行了解密)

如果没有k4ybj这把密钥的话,C4HU/E5dCxuF/hc7sflZWg这堆加密内容表达的信息我们是不知道的。

非对称加密RSA

非对称加密算法是许多计算机应用的基石,其数学支撑是欧拉定理,具体算法比较复杂,这里只简单介绍这种算法的用法。非对称加密的基本用法为:

  1. 基于RSA算法,可生成一个钥匙对,公钥Public和私钥Private,只得到Public或Private中的任意一把,无法算出另外一把
  2. 用Private加密的内容,Public可解密
  3. 用Public加密的内容,Private可解密

你好 -- Private加密 --> lF9iopuOoG09PgLBl

lF9iopuOoG09PgLBl -- Public解密 --> 你好

你也好啊 -- Public加密 --> 8PixXpUwpPf9XTJ5nhF9tQ

8PixXpUwpPf9XTJ5nhF9tQ -- Private解密 --> 你也好啊

让我们加密传输吧

在了解了AES和RSA后,我们可以将通信的内容进行加密了。

AES加密传输

我们使用AES来通信,一个最简单的请求为:

发送方A: 你好 -- AES加密 --> C4HU/E5dCxuF/hc7sflZWg (使用密钥k4ybj对原文“你好”进行了加密)

接收方B: C4HU/E5dCxuF/hc7sflZWg -- AES解密 --> 你好 (使用密钥k4ybj对加密内容进行了解密)

这下在网络中传输的内容,不再是明文,而是“C4HU/E5dCxuF/hc7sflZWg”这一串加密后的内容,如果C不知道密钥k4ybj的话,我们的传输就安全了(C无法窃听到内容,如果篡改内容,B用密钥k4ybj解密也不对)

这种方式通信的问题就在于,密钥k4ybj如果被C知道了,那么整个传输过程也就不再安全了。在AES加密传输过程建立前,常常先需要告知对方AES密钥,此时的传输是明文的,C在这一步就可能先窃听到了密钥,如果C已得到密钥,那么后续的加密也就不再安全。

HTTPS安全连接一旦建立,其具体的传输过程其实就是如上所说对称加密的,关键点变成了如何将密钥k4ybj保密的发给对方。也就是安全连接的建立。这下轮到RSA登场了。

RSA加密

为了让C无法窃听到AES密钥k4ybj,我们使用RSA算法来加密传输这把很关键的密钥。

首先,A和B都使用RSA算法生成自己的密钥对,共有4把:

  • A-Private
  • A-Public
  • B-Private
  • B-Public

Public钥匙都公开,Private自己保管好不对外公布。

加密传输密钥的完整过程如下:

  1. A先通知B,希望和B进行安全通信
  2. B将B-Public返回给A
  3. A用B-Public加密传输A-Public给B
  4. B用B-Private解密后得到A-Public
  5. B用A-Public加密传输密钥k4ybj给A
  6. A用A-Private解密后得到k4ybj
  7. 后续双方使用k4ybj将内容对称加密通信

仔细观察整个过程,即使C一直在窃听整个通信过程,由于不知道A-Private,所以C是无法得到密钥k4ybj的。那么,我们的传输就肯定安全了吗?

并不是!下面我们来聊聊中间人的篡改攻击。

中间人的再度攻击

中间人一旦有篡改消息内容的能力,那么在前面所讲加密传输密钥过程的第2步,可恶的中间人就可以将B-Public替换成它自己的C-Public,将C-Public返回给A,而A以为这是B-Public,用其加密后的内容,C可以用C-Private解密获得,此时C再把C-Public给B,此后A和B拿到的都是C-Public,而双方都以为拿到的是对方的Public。与此同时,C由于拿到了A和B的Public,自己能够用C-Private解密A和B用C-Public加密的内容,所以C达成了通信过程的窃听和篡改。(绕晕了吗?)

中间人之所以能够攻击,是因为我们无法得知B返回的B-Public是否确实是B的没有被篡改或替换。在使用许多应用了不对称加密的应用时,例如ssh,第一次建立连接时,会显示一个密钥的指纹,即B-Public的指纹,问我们是否信任该公钥确实是B的B-Public。如果我们回答yes,就表示信任这个就是B的B-Public了。

如何才能保证B-Public正确且没被篡改呢?下一步,我们引入第三方来解决这个中间人的问题。

权威的证书颁发机构CA

CA要达到的目标,是对B的公钥B-Public进行验证,保证B-Public确实是B的公钥。CA通过颁发证书来达成这个目标。

如何证明B-Public确实是B的公钥呢?有点像证明你妈是你妈,然而我们确实是有办法的。

CA自己有一对钥匙,CA-Private和CA-Public。

要证明B自己的B-Public确实是自己的,B首先去CA申请一种叫做证书的东西。这个证书是一段由CA根据特定算法生成的信息,其包含很多东西,其中有:

  • CA信息
  • B的网址
  • CA-Private加密的B-Public
  • CA-Private加密的证书Hash(证书的Hash又称作签名)

B拿到CA颁发的证书后,当A希望和B通信时,B不是返回给A自己的B-Public,而是把证书给A。

CA的信息是公开的,由各大浏览器和操作系统维护。A拿到B的证书后,根据证书的CA信息取出对应CA的CA-Public,用CA-Public解密出B-Public和证书Hash(签名),A自己用相同逻辑对证书进行Hash,如果和解密出的证书Hash(签名)一致,代表证书有效,此时用CA-Public解密得到的B-Public得证确实是B的。

中间人如果替换证书呢?假设中间人偷偷替换了B的证书发给A,A用CA-Public解密的时候,是无法通过的,除非C能知道CA-Private。

至此,整个安全传输过程结束了,HTTPS具体的实现和本例并不一样,但基本原理大致如上所述。