<commit_before>+++
date = "2016-05-04T21:46:00+08:00"
description = "HTTPS的运行机制概述"
draft = true
tags = ["SSL","TLS"]
title = "HTTPS的运行机制概述"
topics = ["HTTPS"]

+++

本文主要介绍HTTPS的运行机制,不涉及具体实现的细节,如果想了解这方面的内容,可参考[RFC文档](https://tools.ietf.org/html/rfc5246 "RFC文档")。

HTTPS是身披SSL外壳的HTTP,是为了解决HTTP在数据传输时有以下缺点而设计的。

+ 通信使用明文(不加密),内容可能会被窃听。

+ 不验证通信方的身份,因此有可能遭遇伪装。

+ 无法证明报文的完整性,所以有可能已遭篡改。<!--more-->

为了解决以上三大风险,HTTPS分别对应使用了以下三种方法:

+ 加密通信,防止被窃听。

+ 使用证书,验证身份。

+ 提供认证,一旦被篡改,双方会立刻发现。

因此,就可以得出,HTTPS=HTTP+加密+认证+完整性保护。

## HTTPS加密

SSL采用的是一种叫做**公开密钥加密**的方式,在了解公开密钥加密方式之前,先来了解一个与公开密钥加密方式相关的加密方式,
叫做**共享密钥加密**,也叫**对称密钥加密**。
共享密钥加密方式加密和揭秘是共享使用相同的密钥,因此在加密时就必须把密钥发送给对方,这就会造成一个问题,
如何才能把密钥安全地转交呢?如果密钥落入攻击者的手中,那么密钥也就失去了意义。

使用公开密钥加密方式避免了共享密钥加密方式的密钥转发的问题。公开密钥加密使用一对非对称的密钥,
一把叫做**公开密钥**(public key),一把叫做**私有密钥**(private key)。<commit_msg>https<commit_after>+++
date = "2016-05-04T21:46:00+08:00"
description = "HTTPS的运行机制概述"
draft = true
tags = ["SSL","TLS"]
title = "HTTPS的运行机制概述"
topics = ["HTTPS"]

+++

本文主要介绍HTTPS的运行机制,不涉及具体实现的细节,如果想了解这方面的内容,可参考[RFC文档](https://tools.ietf.org/html/rfc5246 "RFC文档")。

HTTPS是身披SSL外壳的HTTP,是为了解决HTTP在数据传输时有以下缺点而设计的。

+ 通信使用明文(不加密),内容可能会被窃听。

+ 不验证通信方的身份,因此有可能遭遇伪装。

+ 无法证明报文的完整性,所以有可能已遭篡改。<!--more-->

为了解决以上三大风险,HTTPS分别对应使用了以下三种方法:

+ 加密通信,防止被窃听。

+ 使用证书,验证身份。

+ 提供认证,一旦被篡改,双方会立刻发现。

因此,就可以得出,HTTPS=HTTP+加密+认证+完整性保护。

## HTTPS加密

SSL采用的是一种叫做**公开密钥加密**的方式,在了解公开密钥加密方式之前,先来了解一个与公开密钥加密方式相关的加密方式,
叫做**共享密钥加密**,也叫**对称密钥加密**。
共享密钥加密方式加密和揭秘是共享使用相同的密钥,因此在加密时就必须把密钥发送给对方,这就会造成一个问题,
如何才能把密钥安全地转交呢?如果密钥落入攻击者的手中,那么密钥也就失去了意义。

使用公开密钥加密方式避免了共享密钥加密方式的密钥转发的问题。公开密钥加密使用一对非对称的密钥,
一把叫做**公开密钥**(public key),一把叫做**私有密钥**(private key)。私有密钥不能让任何其他人知道,
而公开密钥则可以随意发布。

使用公开密钥加密方式的基本流程是,客户端向服务端索要公钥,然后客户端使用公钥加密数据,发送至服务端,
服务端使用自己的私钥再进行解密。这里会产生的两个问题是:

1. 如何确保服务端拿到的公钥是货真价实的公钥,而不是在转交的过程中已经被篡改了?

2. 由于加密解密都需要计算,因此会消耗CPU,那么如何确保服务端处理的性能呢?

针对以上两个问题,HTTPS的解决方案是:

1. 使用证书的机制。

2. HTTPS采用混合加密的方式,组合多种加密方式,在交换密钥环节使用公开密钥加密,建立了安全的连接后,
使用共享密钥加密的方式进行通信,提高处理请求的性能。

## 数字证书

数字证书的引入是为了解决服务端拿到的公钥的的确确就是服务端发出的,也就是能够确认服务端的身份。
数字证书一般由**数字证书认证机构**(CA,Certificate Authority)和其相关机构办法。

数字证书的认证过程为,首先服务器运营人员提出申请,把自己的公钥登录至数字证书认证机构,
数字证书认证机构在验证了申请者的身份之后,使用自己的私钥对服务器的公钥做数字签名,并颁发数字证书,
也就是公钥证书,并且与申请的公钥绑定。

在与客户端通信的时候,服务端会将公钥证书发送至客户端,客户端使用数字证书认证机构的公开密钥,
对收到的公钥证书进行验证,以确认服务器的公钥的真实性。

这里会产生的一个问题是,怎样才能安全获得数字认证机构的公开密钥呢?其实在大多数浏览器中都已经内置了一些权威的数字证书认证机构的公钥,
这些证书称为**根证书**(Root Certificate)。

![Root Certificate](http://7xsskq.com2.z0.glb.clouddn.com/blog/https-ssl-tls/root-certificate.png "Root Certificate")

当然,如果使用OpenSSL开源程序,那么我们自己可以给自己颁发证书,这种由自认证机构颁发的证书称为自签名证书,
但是自签名证书似乎并没有什么用途,浏览器无法识别自签名的证书,因为在访问使用自签名证书的站点时,会弹出安全警告。

## HTTPS的通信过程

在了解了HTTPS所采用的一些机制后,再来看一下HTTPS的整个通信过程。
{'fraction_non_alphanumeric': 0.13846737481031868, 'fraction_numerical': 0.019347496206373292, 'mean_word_length': 11.380281690140846, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2255265', 'n_tokens_mistral': 2213, 'n_tokens_neox': 2724, 'n_words': 98}