# Https


<!--more-->


## 1.概念

HTTPS（HyperText Transfer Protocol over Secure Socket Layer）超文本传输安全协议， 近两年Google、Baidu、Facebook 等这样的互联网巨头，不谋而合地开始大力推行 HTTPS， 国内外的大型互联网公司很多也都已经启用了全站 HTTPS，这也是未来互联网发展的趋势。

> 为鼓励全球网站的 HTTPS 实现，一些互联网公司都提出了自己的要求： 
>
> - Google 已调整搜索引擎算法，让采用 HTTPS 的网站在搜索中排名更靠前；
> - 从 2017 年开始，Chrome 浏览器已把采用 HTTP 协议的网站标记为不安全网站；
> - 苹果要求 2017 年 App Store 中的所有应用都必须使用 HTTPS 加密连接；当前国内炒的很火热的微信小程序也要求必须使用 HTTPS 协议；
> - 新一代的 HTTP/2 协议的支持需以 HTTPS 为基础。

作用：

- 对数据进行加密，并建立一个信息安全通道，来保证传输过程中的数据安全
- 对网站服务器进行真实身份认证

使用特征：

- 使用HTTPS通信时，不再用http://，而是改用https://。另外，
- 当浏览器访问HTTPS通信有效的Web网站时，浏览器的地址栏内会出现一个带锁的标记。

## 2.架构图

HTTPS并非是应用层一个新的协议，通常 HTTP 直接和 TCP 通信，HTTPS则先和安全层（SSL/TLS）通信，然后安全层再和 TCP 层通信。

![img_30](https://img.zhaojq.top/20260727091934730.png "img_30")

SSL/TLS协议就是为了解决上面提到的HTTP存在的问题而生的:

- 所有的信息都是加密传输的，第三方无法窃听
- 配备身份验证（服务端程序），防止身份被冒充
- 具有校验机制，一旦被篡改，通信双方会立刻发现

## 3.https工作原理

HTTPS是身披SSL/TLS外壳的HTTP

**TLS**全称传输层安全协议Transport Layer Security Protocol，TLS/SSL是一种加密通道的规范。

| 协议版本 | 描述                                                         |
| -------- | ------------------------------------------------------------ |
| SSL1.0   | 存在严重的安全漏洞,从未公开过                                |
| SSL2.0   | 2.0版本在1995年2月发布，但因为存在数个严重的安全漏洞而被3.0版本替代 |
| SSL3.0   | 3.0版本在1996年发布                                          |
| TLS1.0   | IETF对SSL3.0进行了标准化，并添加了少数机制（但是几乎和SSL3.0无差异） |
| TLS1.1   | 在RFC 4346中定义，于2006年4月发表                            |
| TLS1.2   | 在RFC 5246中定义，于2008年8月发表                            |
| TLS1.3   | 在RFC 8446中定义，于2018年8月发表                            |

TLS协议是由**TLS记录协议**（TLS record Protocol）和TLS握手协议（TLS handshake Protocol）这两层协议叠加而成的。

![img_31](https://img.zhaojq.top/20260727091934909.png "img_31")

- 记录协议：TLS Record protocol

  TLS记录协议位于TLS握手协议的下层，是负责使用对称密码对消息进行加密通信的部分
  加密使用的密钥是通过握手协议在服务器和客户端之间协商决定的

- 握手协议：TLS Handshaking Protocols

  由TLS Change Ciper Spec Protocol（密码规格变更协议）和TLS Alert Protocol（警告协议）组成

  > 负责在客户端和服务器之间协商决定密码算法和共享密钥。
  > 密码规格变更协议负责向通信对象传达变更密码方式的信号，当协议中途发生错误时，就会通过警告协议传达给对方。
  > 警告协议是TLS握手协议负责在发送错误时将错误传达给对方。

HTTPS和HTTP协议相比提供了:

- 数据完整性：内容传输经过完整性校验
- 数据隐私性：内容经过对称加密，每个连接生成一个唯一的加密密钥
- 身份认证：第三方无法伪造服务端（客户端）身份

> 其中，数据完整性和隐私性由TLS Record Protocol保证，身份认证由TLS Handshaking Protocols实现。



### 3.1 对称加密算法

**定义**：采用单钥密码系统的加密方法，同一个密钥可以同时用作信息的加密和解密，这种加密方法称为对称加密，也称为**单密钥加密**。

**要素**：原文、秘钥、算法    (秘钥：在密码学中是一个定长的字符串、需要根据加密算法确定其长度)

**工作过程**：对称加密通常使用的是相对较小的密钥，一般小于256 bit。因为密钥越大，加密越强，但加密与解密的过程越慢。如果你只用1 bit来做这个密钥，那黑客们可以先试着用0来解密，不行的话就再用1解；但如果你的密钥有1 MB大，黑客们可能永远也无法破解，但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性，也要照顾到效率。

> 加密：明文 + 密钥 -> 密文
>
> 解密：密文 + 密钥 -> 明文

**算法**:

- DES（Data Encryption Standard）

  数据加密标准（现在用的比较少，因为它的加密强度不够，能够暴力破解）

- 3DES

  原理和DES几乎是一样的，只是使用3个密钥，对相同的数据执行三次加密，增强加密强度。(缺点：要维护3个密钥，大大增加了维护成本) 

- AES（Advanced Encryption Standard）

  高级加密标准，用来替代原先的DES，目前美国国家安全局使用的，苹果的钥匙串访问采用的就AES加密。是现在公认的最安全的加密方式，是对称密钥加密中最流行的算法。

  AES128和AES256主要区别是密钥长度不同（分别是128bits,256bits)、加密处理轮数不同（分别是10轮，14轮），后者强度高于前者。

**特点**：

- 优点：算法公开、计算量小、加密速度快、加密效率高
- 缺点：相对来说不算特别安全，只有一把钥匙，密文如果被拦截，且密钥也被劫持，那么，信息很容易被破译

**推演**：为了防止上述现象的发生，人们想到一个办法：对传输的信息加密（即使黑客截获，也无法破解）

> 加密公式： f1 ( key（密钥），data )  = X（密文）
>
> 解密公式： f2 ( key（密钥），X（密文） )  = data
>
>  
>
> 缺陷：加密和解密同用一个密钥，加密和解密都会用到密钥，没有密钥就无法对密码解密，反过来说，任何人只要持有密钥就能解密。
> 改进：比如服务器为每一个客户端请求的TCP连接生成一个唯一的key (但由于不同客户端、服务器数量庞大，所以双方都需要维护大量的密钥，维护成本高，每个客户端服务端的安全级别不同，密钥也极易泄露)



### 3.2 非对称加密算法

**简介**：非对称加密是计算机通信安全的基石，保证了加密数据不会被破解。 非对称加密算法需要两个密钥：**公开密钥**(public key) 和**私有密钥**(private key) ，公开密钥和私有密钥是一对

**特点**：

- 如果用公开密钥对数据进行加密，只有用对应的私有密钥才能解密。
-  如果用私有密钥对数据进行加密，只有用对应的公开密钥才能解密。
- 由于其算法复杂，而使得加密、解密速度没有对称加密解密的速度快。有两种密钥，其中一个是公开的，这样就可以不需要像对称密码那样传输对方的密钥了，这样安全性就大了很多。
- 私钥保存在服务端，公钥保存在客户端，私钥永远不对外暴露

**常用算法**：RSA, DSA, ECDSA

**缺陷**：公钥是公开的，则用私钥加密的信息，则可能被窃取用公钥进行解密

**组合使用**：非对称加密既然也有缺陷，那我们就将对称加密，非对称加密两者结合起来，取其精华、去其糟粕，发挥两者的各自的优势。

![img_32](https://img.zhaojq.top/20260727091935093.png "img_32")

通过对称加密和非对称加密的组合使用，解决内容可能被窃听的问题,但是仍存在以下缺陷：

- 报文可能遭篡改----使用数字签名解决
- 通信方身份可能被伪装-----使用数字证书解决

### 3.3 数字签名

**功能**：

- 能确定消息确实是由发送方签名并发出来的，因为别人假冒不了发送方的签名。
- 数字签名能确定消息的完整性,证明数据是否未被篡改过。

**数字签名生成**：

![img_33](https://img.zhaojq.top/20260727091935298.png "img_33")

> 将要发送的数据先用Hash算法（摘要算法、散列算法）生成消息摘要，然后用发送者的私钥加密生成数字签名，与原文一起传送给接收者。
>
> - MD(Message Digest)：消息摘要算法
> - SHA(Secure Hash Algorithm)：安全散列算法
> - MAC(Message Authentication Code)：消息认证码

**数字签名校验流程**：

![img_34](https://img.zhaojq.top/20260727091935484.png "img_34")

> 接收者只有用发送者的公钥才能解密被加密的摘要信息，然后用HASH函数对收到的原文产生一个摘要信息，与上一步得到的摘要信息对比。如果相同，则说明收到的信息是完整的，在传输过程中没有被修改，否则说明信息被修改过，因此数字签名能够验证信息的完整性。

假设消息传递在客户端、服务器之间发生。服务器将消息连同数字签名一起发送给客户端，客户端接收到消息后，通过校验数字签名，就可以验证接收到的消息就是服务器发送的。

这个过程的前提是客户端知道服务器的公钥。问题的关键的是，和消息本身一样，公钥不能在不安全的网络中直接发送给客户端，或者说拿到的公钥如何证明是服务器的。此时就需要引入了证书颁发机构（Certificate Authority，简称CA），CA数量并不多，客户端内置了所有受信任CA的证书。

### 3.4 证书

**数字证书**：是一个经证书认证结构数字签名的包含公开密钥、拥有者信息的文件，有点像生活中的身份证、护照等，是由一个官方的证书颁发机构签发的一组数据。这种证书很难伪造，用于使用者的身份证明。

实际上，我们使用的证书分很多种类型，SSL证书只是其中的一种，SSL证书负责传输公钥。我们常见的证书根据用途不同大致有以下几种：

- SSL证书，用于加密HTTP协议，也就是HTTPS，TLS。如果一个web应用想要升级为https，需要购买证书。
- 代码签名证书，用于签名二进制文件，比如Windows内核驱动，Firefox插件，Java代码签名等等
- 客户端证书，用于加密邮件
- 双因素证书，网银专业版使用的USB Key里面用的就是这种类型的证书

> 证书中包含：组织信息、域名信息、公钥（比如拉勾教育的公钥）、证书有效期等信息。

**CA - 数字证书认证机构**：

CA是证书的签发机构，它是公钥基础设施（Public Key Infrastructure， PKI）的核心。CA是负责签发证书、认证证书、管理已颁发证书的机关。

**认证过程(升级https)**:

1. 服务器的运营人员（拉勾网站的运营）向第三方机构CA（或者其代理机构）提交公钥、组织信息、域名等信息并申请认证;
2. CA通过线上、线下等多种手段验证申请者提供信息的真实性，如组织是否存在、企业是否合法，是否拥有域名的所有权等;

3. 如信息审核通过，CA会向申请者签发认证文件-证书。

   > 证书包含以下信息：
   >         申请者公钥（如拉勾教育的公钥）、申请者的组织信息和个人信息、签发机构 的信息、有效时间、证书序列号等信息的明文，同时包含一个CA机构的数字签名。 其中签名的产生算法：首先，使用散列函数计算公开的明文信息的信息摘要，然后，采用 CA的私钥对信息摘要进行加密，密文即签名；

   ![img_35](https://img.zhaojq.top/20260727091935687.png "img_35")

   > 用户向web服务器发起一个安全连接的请求服务器返回经过CA认证的数字证书，证书里面包含了服务器的public key。
   >
   > 用户拿到数字证书，怎么确保CA证书不被劫持，黑客完全可以把一个假的CA证书发给Client，进而欺骗Client，用户如何编写证书真伪？
   >
   > CA的大杀器就是，CA把自己的CA证书集成在了浏览器和操作系统里面。 Client拿到浏览器或者操作系统的时候，已经有了CA证书，没有必要通过网络获取，那自然也不存在劫持的问题。
   >
   > 查看浏览器CA证书：设置-->安全检查-->安全-->管理证书
   > 查看操作系统CA证书：certmgr.msc
   >
   >  
   >
   > Client 读取证书中的相关的明文信息，采用相同的散列函数计算得到信息摘要，然后利用对应 CA的公钥解密签名数据，对比证书的信息摘要，如果一致，则可以确认证书的合法性，即服务器的公开密钥是值得信赖的。
   >
   > 客户端还会验证证书相关的域名信息、有效时间等信息; 客户端会内置信任CA的证书信息(包含公钥)，如果CA不被信任，则找不到对应 CA的证书，证书也会被判定非法。

**ssl证书分类**：

- DV（域名型SSL）：个人站点
- OV（企业型SSL）：企业官网
- EV（增强型SSL）：对安全需求更强的企业官网、电商、互联网金融网站

### 3.5 完整的https通信

**TLS握手过程**： 明文----->非对称加密----->对称加密

**第一步**: 浏览器给出TLS协议版本号、一个客户端生成的随机数1（Client random），以及客户端支持的加密方法。（明文通讯）

![img_36](https://img.zhaojq.top/20260727091935892.png "img_36")

**第二步**: 服务器确认双方使用的加密方法，并给出数字证书、以及一个服务器生成的随机数2（Server random）。（明文通讯）

![img_37](https://img.zhaojq.top/20260727091936158.png "img_37")

**第三步**: 浏览器确认数字证书有效，然后生成一个新的随机数3（Pre-master secret），并使用数字证书中的公钥加密这个随机数，发给服务器。（使用非对称加密算法）

浏览器确认数字证书有效：浏览器和操作系统内部内置了很多CA机构的证书，是否篡改、是否在有效期内、域名和访问的网站是否匹配。

**第四步**: 服务端使用自己的私钥，获取客户端发来的随机数（即Premaster secret）。

双方就都有三个一模一样的随机数，前两个是明文发送的，最后客户端生成的这个是使用证书中的公钥密文发送的。

**第五步**: 客户端和服务器根据约定的加密方法，使用前面的三个随机数经过特定的算法，生成"对话密钥"（session key），用来加密接下来的整个对话过程。

对话密钥，又叫做会话密钥，其实就是讲之前通讯中的三个随机数生成一个密钥（对称加密）

三个随机数----->第三个是使用非对称加密---->相同的算法------->会话密钥

**第六步**：客户端和服务器都会第一次使用会话密钥加密一个消息发送给对方。

> 客户端收到服务端发送的Certificate 报文后首先会校验证书的合法性：
>
> - 证书路径信任链逐级校验通过（证书确由可信 CA 认证签发）；
> - 签名解密成功（确系证书持有者亲笔）； 
> - 从签名解析出的摘要和证书公开内容的摘要一致（证书内容完整，未被篡改）；
> - 主题子域与 URL 中的 HOST 一致，综上确保访问的网站是来自预期目标服务器且非劫持或钓鱼。

**session的恢复**：

握手阶段用来建立SSL连接。如果出于某种原因，对话中断，就需要重新握手。

这时有两种方法可以恢复原来的session：一种叫做**session ID**，另一种叫做**session ticket**。

- Session ID

  session ID的思想很简单，就是每一次对话都有一个编号（session ID）。如果对话中断，下次重连的时候，只要客户端给出这个编号，且服务器有这个编号的记录，双方就可以重新使用已有的"对话密钥"，而不必重新生成一把。

  ![img_38](https://img.zhaojq.top/20260727091936407.png "img_38")

  如图中，客户端给出session ID，服务器确认该编号存在，双方就不再进行握手阶段剩余的步骤，而直接用已有的对话密钥进行加密通信。

  session ID是目前所有浏览器都支持的方法，但是它的缺点在于session ID往往只保留在一台服务器上。所以，如果客户端的请求发到另一台服务器，就无法恢复对话。session ticket就是为了解决这个问题而诞生的，目前只有Firefox和Chrome浏览器支持。

- session ticket

  ![img_39](https://img.zhaojq.top/20260727091936588.png "img_39")

  如上图中，客户端不再发送session ID，而是发送一个服务器在上一次对话中发送过来的session ticket。这个session ticket是加密的，只有服务器才能解密，其中包括本次对话的主要信息，比如对话密钥和加密方法。当服务器收到session ticket以后，解密后就不必重新生成对话密钥了。

## 4.ca证书制作实战

使用自签名证书来构建安全网络，所谓自签名证书，就是自己扮演 CA 机构，自己给自己的服务器颁发证书。

### 4.1 OpenSSL

 OpenSSL是一个以C语言编写现了SSL与TLS协议的开源的软件库包，应用程序可以使用这个包来进行安全通信，避免窃听，同时确认另一端连线者的身份。这个包广泛被应用在互联网的网页服务器上。OpenSSL支持Linux、 Windows、BSD（Unix的衍生系统）、Mac等平台，这使得OpenSSL具有广泛的适用性。

OpenSSL整个软件包大概可以分成三个主要的功能部分：

- 加密算法库

  - 对称加密算法

  - 非对称加密算法

  - 信息摘要算法

- ssl协议库

  - OpenSSL实现了SSL协议的SSLv2和SSLv3，支持了其中绝大部分算法协议
  - OpenSSL也实现了TLSv1.0+

- 应用程序

  多功能的命令行工具，可以实现加密解密、密钥生成、密钥和证书管理、自建CA和签名等功能

### 4.2 过程

1. CA生成根密钥
2. CA生成根证书
3. Nginx生成私钥
4. Nginx申请证书
5. CA签发
6. Nginx安装证书，配置



### 4.3 颁发证书

默认情况下Linux操作系统已经内置安装了OpenSSL，可以通过version查看版本号

- 修改配置

  在CA目录下创建两个初始文件，维护序列号。通过CA机构签发的每个证书都有一个唯一的序列号  `touch index.txt serial`

- 生成根密钥

  表示的CA机构的私钥，CA结构签发的每一个证书都要通过自己的私钥进行签名

  进入index.txt目录，生成一个2048位密钥`openssl genrsa -out private/cakey.pem 2048`

- 生成根证书

  使用req命令生成自签证书

  > - new：表示新的申请
  > - x509：表示生成自签证书
  > - key：指定私钥文件
  >
  > - out：保存证书的位置
  > - days：指定证书期限

  `openssl req -new -x509 -key private/cakey.pem -out cacert.pem`

  > 会提示输入一些内容，因为是私有的，所以可以随便输入（之前修改的openssl.cnf会在这里呈现），最好记住能与后面保持一致。

- 为nginx服务器生成ssl密钥
  申请SSL证书本质上就是服务器升级支持HTTPS，非对称加密（公钥和私钥）。
  安装nginx，为nginx生成ssl密钥

  ```shell
  cd /etc/nginx/ssl
  #为nginx web服务器生成ssl密钥
  openssl genrsa -out nginx.key 2048
  ```

- 为nginx生成证书签署请求

  该过程会生成一个文件，包含了证书相关的信息，但是该文件不是证书，生成证书的请求文件。

  该文件需要发送给CA机构，由CA签名后生成一个证书文件。

  `openssl req -new -key nginx.key -out nginx.csr`

  > 注意与前面输入的信息保持一致

- 私有CA根据请求来签署证书

  接下来要把上一步生成的证书请求csr文件，发到CA服务器上，` openssl ca -in nginx.csr -out nginx.crt`

  > 上面签发过程其实默认使用了-cert cacert.pem -keyfile cakey.pem，这两个文件就是前两步生成的位于前面/etc/pki/CA下的根密钥和根证书。将生成的crt证书发回nginx服务器使用。
  >
  > 到此我们已经拥有了建立SSL安全连接所需要的所有文件，并且服务器的crt和key都位于配置的目录下，剩下的是如何使用证书的问题。






