Skip to content

HTTPS模块 ​

HTTPS协议 ​

HTTPS可以保证数据在传输过程中不被篡改,如果使用HTTP协议,那么服务器和客户端的数据传输是明文传输,现在都使用HTTPS协议,本节主要介绍HTTPS协议如何保证传输安全.

从最简单的开始,A和B要进行通信,如果中间没有第三方,A直接把数据拿给B,B也直接把数据拿给A,那么这不可能出现数据泄露,但我们数据传输需要经过很多节点,这些节点可能会被植入一些病毒,如果我们使用HTTP协议来明文传输,病毒可以很轻松地从这些节点获取到我们的信息,这非常不安全

画板

为了防止数据泄露,我们采用加密,加密分为两种,对称加密和非对称加密

先来介绍对称加密,所谓的对称加密,就是一个秘钥可以同时完成加密和解密两个过程

画板

以上图例就是一个对称加密,有了这个key之后,我们可以用明文和key两个参数通过加密算法,对明文进行加密,加密之后得到密文,将密文进行传输,传输完成后,接收方收到密文,再用这个key和密文作为参数,经过一个解密算法进行解密,可以得到明文,这就是对称加密的思想,也保证了传输过程中数据不被篡改和泄露,这种方式也叫作单密钥加密

常用的对称加密算法为:DES,3DES,AES,Blowfish等

我们常见的压缩包加密使用的其实就是一种对称加密算法,秘钥就是我们设置的密码,可以通过这个密码加密,也可以通过这个密码解密

但是这种方式也存在很严重的问题,参考下面的图例,下面是一个A向B传输信息的图示

画板

这种做法的劣势显而易见,要实现对称加密,秘钥key必须是双方都知道的,你必须把秘钥传输给对方,如何把key传输给对方就是个问题,如果第一次传输的key都被截获了,那么传输的密文也毫无意义.

为了解决秘钥的传输问题,我们引入非对称加密,在对称加密中,加密和解密都用一个秘钥,而在非对称加密中,秘钥有两个,一个用来加密,一个用来解密,我们把这两个秘钥称为私钥和公钥,公钥一般是公开的,私钥是必须要保密的,这俩是一对,你用私钥加密,那么就只能用这个公钥解密,你用公钥加密就只能用私钥解密.

如果您想要保证数据的安全传输,那么您应该用公钥加密,用私钥解密.这样只有持有私钥的人才能看到数据的内容.

如果您想要对数据进行数字签名,那么您应该用私钥加密,用公钥解密.这样所有持有公钥的人都可以验证数据的来源和完整性.

画板

一般来说,我们要保证数据安全传输,我们采用公钥加密,私钥解密,我们只允许有私钥的用户解密我们的信息

常见的非对称加密算法有RSA,Elgamal,D-H,ECC等

但是这样也有问题,参考下图

画板

公钥是公开的,可以由B以明文的方式传输给A,A通过公钥加密后传输给B,B收到后可以用私钥解密,但私钥是保密的,A是没有B的私钥的,所以当B想向A响应一个信息的时候,使用公钥加密,A是无法解密的,所以这种方式只能实现数据的单向传递,不能实现数据的双向传递.

为了解决双向通信的问题,我们把对称加密和非对称加密联系起来

画板

这种方式,A需要向B传输数据,A先生成一个秘钥key2,使用key1的公钥加密将秘钥key2传输给B,此时这个加密数据只有B可以拿到,B拿到key2之后,A和B之间的通信均使用key2的对称加密即可.

画板

可以看到,哪怕第三方在半路截胡了,产生了一个新的秘钥key3,你只能拿到服务端第一次响应的数据,由于你没有key2,你根本不可能用key2进行封装在传给客户端,客户端也能及时发现问题

这种方式可以防止数据不泄露,但无法保证数据不被篡改

画板

可见,如果在传输公钥的时候出现了问题,公钥被篡改,那这种加密方式也不管用了,我们需要解决第一次的公钥传输问题.

此时我们看起来就没有办法了,这时一个第三方机构就出现了,这个第三方机构就是证书颁发机构(CA)

这个CA是权威机构,浏览器,操作系统都会记录世界上已知的证书颁发机构,有了证书颁发机构,我们就可以解决一切问题.

每个服务器想要获取证书颁发机构的服务,都需要获得一个证书,获得证书是需要花钱的,下面是证书的获得流程

  1. 服务器将服务器的域名和服务器的公钥key发给CA
  2. CA自己有一个密钥对,一个公钥和一个私钥,这个私钥是绝对保密的,这个公钥是全世界都知道的
  3. CA收到钱和服务器域名后,会颁发一个电子证书发送给服务器

证书里主要包含以下内容

  • 明文:域名
  • 明文:证书颁发机构
  • CA私钥加密:服务器的公钥key
  • CA私钥加密:证书签名

由于服务器的公钥是用CA的私钥加密,任何人都可以读取到这个服务器的公钥key,但是这个信息是不可能修改的,因为这个数据是用CA私钥加密,CA公钥解密的,你能给他解开,但是你不能再进行加密,因为你获取不到CA的私钥,这就实现了电子签名,能够保证传输的数据不被篡改.

而证书签名也是一个数据,证书签名是将服务器的域名,CA的公钥,服务器的公钥经过一系列算法生成的,这个算法是公开的.

我们拿到一个证书前面后,我们可以根据域名,服务器公钥,CA公钥来算出一个新的证书签名,从而来判断证书签名的内容是否被篡改,签名就是用来验证是否被篡改的.

下面来看详细的步骤

  1. 通信之前,服务器给客户端一个电子证书,浏览器可以根据电子证书找到证书颁发机构,选择对应的公钥
  2. 浏览器拿到证书后,通过相应颁发机构的公钥,解密服务器的公钥和证书签名
  3. 此时浏览器有了域名+服务器公钥+CA公钥,我们经过一些算法,算出一个证书签名,来验证签名是否正确,如果签名正确,说明公钥没有被篡改.
  4. 此时服务器就安全的将公钥传输给了客户端.

此时第三方在这一步是无法篡改的,第三方哪怕截获了证书,他只能拿到域名和证书机构,加上CA秘钥加密的公钥key和证书签名,这个服务器公钥你可以读出来,但是你无法篡改,因为服务器公钥和证书签名都是CA私钥加密的,你哪怕可以解开,你也无法再去加密成原来的样子,你一旦篡改了那客户端也能及时发现问题,而你也不能去修改域名,因为域名一旦被修改,证书签名的验证就会出问题,所以这个信息是肯定可以安全传输到客户端的.

这样我们就解决了第一次公钥传输的问题,这就是https的加密流程,我们总结流程如下

  1. 服务器事先花钱从CA获取一个电子证书,证书主要包含了域名,证书机构,CA私钥加密的服务器公钥,CA私钥加密的证书签名
  2. 开始通信,服务器向客户端发送一个电子证书
  3. 客户端收到电子证书,通过证书机构选择公钥,解密服务器公钥和证书签名,由于服务器公钥和证书签名是CA私钥加密,所以不可篡改
  4. 通过证书里的域名,服务器公钥,CA公钥,验证证书签名,如果验证失败,说明证书被篡改
  5. 此时客户端拿到了服务器公钥,客户端生成一个新的对称加密的秘钥key2,通过服务器公钥加密后发送给服务器
  6. 服务器可以顺利拿到这个秘钥,因为这个加密数据需要用服务器的私钥解密,第三方无法获取
  7. 客户端和服务器可以通过这个对称加密的密钥顺利通信

HTTPS相对于HTTP就加了一个SSL的协议,也就是加密协议,也就是上面的算法,如果一个网站是HTTPS协议拿到的,那么浏览器希望这个网站的所有数据都是用HTTPS协议获取的,而不是HTTP协议.

HTTPS的默认端口为443

搭建HTTPS服务器 ​

在实际项目中,不会用NODEJS搭建一个NODEJS模块,因为服务器结构不会这么简单,这里我们写的是一个很简单的服务器结构,由NODE服务器来监听443端口,由node搭建HTTPS服务器

实际上开发中,node服务器就是一个普普通通的服务器,由NGINX服务器来使用HTTPS,由nginx服务器做请求转发,而且node服务器部署之后,端口会屏蔽,只能允许内部访问.

要搭建HTTPS服务器,首先要准备证书,要么去网上买,要么自己本地生成,本地生成非常麻烦,我们只能把自己当成权威机构,自己颁发证书,具体步骤如下

  1. 安装openssl
    1. 下载源码,自行构建https://github.com/openssl/openssl
    2. 下载windows安装包https://slproweb.com/products/Win32OpenSSL.html
    3. mac下自带
    4. 通过输入命令openssl测试
  2. 生成CA私钥
    1. openssl genrsa -des3 -out ca-pri-key.pem 1024
    2. genrsa:密钥对生成算法
    3. -des3:使用对称加密算法des3对私钥进一步加密
      1. 命令运行过程中会让用户输入密码,该密码将作为des3算法的key
    4. -out ca-pri-key.pem:将加密后的私钥保存到当前目录的ca-pri-key.pem文件中
      1. pem:Privacy-Enhanced Mail (PEM)
    5. 1024:私钥的字节数
  3. 生成CA公钥(证书请求)
    1. openssl req -new -key ca-pri-key.pem -out ca-pub-key.pem
    2. 通过私钥文件ca-pri-key.pem中的内容,生成对应的公钥,保存到ca-pub-key.pem中
    3. 运行过程中要使用之前输入的密码来实现对私钥文件的解密
    4. 其他输入信息
      1. Country Name:国家名 CN
      2. Province Name:省份名 Sichuan
      3. Local Name:城市名
      4. Company Name:公司名
      5. Unit Name:部门名
      6. Common Name:站点名
      7. ...
  4. 生成CA证书 1. openssl x509 -req -in ca-pub-key.pem -signkey ca-pri-key.pem -out ca-cert.crt 2. 使用X.509证书标准,通过证书请求文件ca-pub-key.pem生成证书,并使用私钥ca-pri-key.pem加密,然后把证书保存到ca-cert.crt文件中
  5. ------华丽的分割线-------
  6. 生成服务器私钥
    1. openssl genrsa -out server-key.pem 1024
  7. 生成服务器公钥
    1. openssl req -new -key server-key.pem -out server-scr.pem
  8. 生成服务器证书
    1. openssl x509 -req -CA ca-cert.crt -CAkey ca-pri-key.pem -CAcreateserial -in server-scr.pem -out server-cert.crt

以笔记为镜,可以知得失