2021-09-07

我们在平时在使用浏览器浏览网页时,通常会看到网址前面写的是https,这表明当前网站通过https协议来进行数据的传输。那么https和http有什么不同的呢?
本文将通过介绍HTTP和HTTPS、公钥私钥、加密、数字证书等方面的内容来帮助读者理解HTTPS。

HTTPS(全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目的的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程中的安全性。HTTPS在HTTP的基础下加入SSL,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。 ————百度百科

HTTP和HTTPS区别

上面是引自百度百科的介绍,要理解HTTPS,首先看一下HTTP和HTTPS的区别。

  • 端口:HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始,且默认使用端口443.
  • 安全性和资源消耗:HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。
  • 对称加密:密钥只有一个,加密和解密为同一个密码,且加密速度快,典型的对称加密算法有DES、AES等。
  • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等

SSL/TLS

SSL全称是Security Sockets Layer,中文叫“安全套接层”。为啥要发明SSL这个协议呢?因为原先互联网上使用的HTTP协议是明文的,存在很多缺点,比如传输内容会被头盔(嗅探)和篡改。发明SSL协议,就是为了解决这些问题。
1999年,SSL因为引用广泛,已经成为互联网上的事实标准。IETF就在那年把SSL标准化。标准化之后名称改为TLS(Transport Layer Security),中文叫做“传输层安全协议”。
很多文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

公钥与私钥

密钥

一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算法。在公钥密码体制中说到的公钥、私钥就是密钥,公钥是加密使用的密钥,私钥是解密使用的密钥。

公钥密码体制

公钥密码体制分为三个部分,公钥、私钥、加密解密算法,它的加密解密过程如下:

  • 加密:通过加密算法和公钥对内容(或者说明文)进行加密,得到密文,加密过程需要用到公钥。
  • 解密:通过解密算法和私钥对密文进行解密,得到明文。解密过程需要用到解密算法和私钥。注意,由公钥加密的内容,只能由私钥进行解密,也就是说,由公钥加密的内容,如果不知道私钥,是无法解密的。

公钥密码体制的公钥和算法都是公开的(这是为什么叫公钥密码体制的原因),私钥是保密的。大家都可以使用公钥进行加密,但是只有私钥的持有者才能解密。在实际的使用中,有需要的人会生成一对公钥和私钥,把公钥发布出去给别人使用,自己保留私钥。

对称加密算法

在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。因此对称加密算法要保证安全性的话,密钥要做好保密,只能让使用的人知道,不能对外公开。这个和上面的公钥密码体制有所不同,公钥密码体制中加密是用公钥,解密用私钥,而对称加密中,加密和解密都是用同一个密钥,不区分公钥和私钥。

非对称加密算法

在非对称加密算法中,加密使用的密钥和解密使用的密钥是不同的,前面所说的公钥密码体制就是一种非对称加密算法,他的公钥和私钥是不能相同的,也就是说加密使用的密钥和解密使用的密钥不同,因此它是一个非对称加密算法。

RSA简介

RSA是一种公钥密码体制,现在用的很广泛。RSA密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。由公钥加密的内容可以并且只能由私钥进行解密,并且由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以并且只能由对方进行解密。

签名和加密

我们说加密,是指对某个内容加密,加密后的内容还可以通过解密进行还原。比如我们把一封邮件进行加密,加密后的内容再网络上进行传输,接受者在收到后,通过解密可以还原邮件的真实内容。

这里主要解释一下签名,签名就是在信息的后面再加上一段内容,可以证明信息没有被修改过,怎么样可以达到这个效果呢?一般是对信息做一个hash计算得到一个hash值,注意,这个过程是不可逆的,也就是说无法通过hash值得出原来的信息内容。在把信息发送出去时,把这个hash值加密后作为一个签名和信息一起发出去。接收方在收到信息后,会重新计算信息的hash值,并和信息所附带的hash值(解密后)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里hash计算可以保证不同的内容一定会得到不同的hash值,所以只要内容一被修改,根据信息内容计算的hash值就会变化。当然,不怀好意的人也可以修改信息内容的同时也修改hash值,从而让它们可以相匹配,为了防止这种情况,hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。至于如何让别人可以解密这个签名,这个过程涉及到数字证书等概念,我们后面再说到数字证书时再详细说明,这里先理解签名这个概念。

数字证书

详细说明参考
数字证书是https实现安全传输的基础,它是由权威的CA机构颁发的,CA机构是负责发放和管理数字证书的权威机构。
数字证书的内容:

  • 证书的发布机构
  • 证书的有效期
  • 公钥
  • 证书所有者
  • 签名所使用的算法
  • 指纹以及指纹算法

数字证书可以保证数字证书里的公钥确实是这个证书的所有者,或者证书可以用来确认对方的身份。也就是说,我们拿到一个数字证书,我们可以判断这个数字证书到底是谁的。

CA机构在给别人颁发证书外,它也有自己的证书,这个证书是机构自己给自己颁发的,为了区分我们称它为根证书,根证书也有自己的公钥和私钥,根公钥和加密算法对外公布的,而根私钥是CA机构自己绝对保密的。这个根证书在验证证书的过程中起着核心的作用。

在证书中有一个叫指纹的字符串,可以理解为证书身份的唯一代表,使用来保证证书的完整性的,确保证书没有被修改过。证书在发布之前,CA机构对证书的内容用指纹算法(一般是sha1或sha256)计算得到一个hash值,这个hash值就是指纹。为什么用hash值作为证书的身份代表呢?首先hash值具有不可逆性,也就是说无法通过hash值得到原来的信息内容;其次,hash值具有唯一性,即hash计算可以保证不同的内容一定得到不同的hash值。

签名是在信息的后面加上一段字符串,可以证明该信息没有被修改过。数字证书在发布的时候,CA机构将证书的指纹和指纹算法通过自己的私钥加密得到就是证书上的签名了。

我们在验证证书的时候,首先通过机构的根公钥去解密证书的签名,解密成功的话会得到证书的指纹和指纹算法,指纹是一个hash值,它代表着证书的原始内容,此时再通过指纹算法计算证书内容得到另一个hash值,如果这两个hash值相同,则代表证书没有被篡改过,否则就是被篡改了。

数字证书的验证

首先浏览器通过URL网址去请求服务器,服务端接收到请求后,就会给浏览器发送一个自己的CA数字证书。浏览器接收到证书后,就要开始进行验证工作了。首先从证书中得知证书的颁发机构,然后从浏览器系统中去寻找此颁发机构的根证书。世界上权威CA机构的根证书都是预先嵌入到浏览器中的,如果在浏览器中没有找到对应的根证书,就代表此机构不是受信任的,那么就会警告无法确认证书的真假,比如以前打开12306网站就会提示,现在就不会了。

如果我们找到了证书颁发机构的根证书,那么就从根证书中取得那个根公钥,用根公钥去解密此证书的数字签名,成功解密的话就得到证书的指纹和指纹算法,指纹是证书内容通过指纹算法计算得到的一个hash值,这里我们称为h1,h1代表证书的原始内容;然后用指纹算法对当前接收到的证书内容再进行一次hash计算得到另一个h2,h2则代表当前证书的内容,如果此时h1和h2是相等的,就代表证书没有被修改过。如果证书被修改过,h1和h2是不可能相同的,因为hash值具有唯一性,不同内容通过hash计算得到的值是不可能相同的。

有人说加入证书上的指纹是不法分子伪造的,伪造是没有用的,因为伪造的指纹不可能用CA机构的根私钥去加密,根私钥是CA机构绝对保密的。伪造者只能拿自己的私钥去加密这个伪造的指纹,但我们拿机构的根公钥去解密伪造指纹的时候是不可能成功的,加密内容只能由一对公钥私钥解密。

在证书没有被修改的基础上,再检查证书上的使用者的URL和我们请求的URL是否相等,如果相等,那么就可以证明当前浏览器链接的网址也是正确的,而不是一些钓鱼网站之类的。

一个加密通信过程

  • 客户端向服务端发送一个通信请求
  • 客户->服务器:你好
  • 服务器向客户发送自己的数字证书。证书中有一个公钥用来加密信息,私钥由服务器持有
  • 服务器->客户:你好,我是服务器,这里是我的数字证书
  • 客户收到服务器的证书后,它会去验证这个数字证书是不是服务器的,数字证书有没有什么问题,数字证书如果检查没有问题,就说明数字证书中的公钥确实是服务器的。检查数字证书后,客户会发送一个随机的字符串给服务器用私钥去加密,服务器把加密的结果返回给客户,客户用公钥解密这个返回结果,如果解密结果与之前的随机字符串一致,那就说明对方确实是私钥的持有者,或者说对方确实是服务器。
  • 客户->服务器:向我证明你就是服务器,这是一个随机字符串
  • 服务器->客户:{一个随机字符串}【私钥|RSA】 //表示用私钥对该随机字符串进行加密
  • 客户使用公钥对加密的随机字符串进行解密,等于之前发送过去的字符串,确定对方是真的服务器
  • 验证服务器的身份后,客户生成一个对称加密算法和密钥,用于后面的通信的加密和解密。这个对称加密算法和密钥,客户会用公钥加密后发送给服务器,别人截获了也没用,因为只有服务器手中有可以解密的密钥。这样,后面服务器和客户就都可以用对称加密算法来加密和解密通信内容了。
  • 客户->服务器:{我们后面的通信过程,用对称加密来进行,这里是对称加密算法和密钥}【公钥|RSA】
  • 服务器->客户:{OK,已经收到你发来的对称加密算法和密钥!有什么可以帮到你的?}【密钥|对称加密算法】
  • 客户->服务器:{我的账号是aaa,密码是123,把我的余额信息发给我看看}【密钥|对称加密算法】
  • 服务器->客户:{你好,你的余额是100元}【密钥|对称加密算法】
  • …………