HTTPS详细整理(干货)

加密算法

对称加密

加密和解密都是使用的同一个密钥。

非对称加密

非对称加密使用一对“私钥-公钥”,用私钥加密的内容只有对应公钥才能解开,反之亦然。非对称加密有以下特性:

  • 对于一个公钥,有且只有一个对应的私钥。
  • 公钥是公开的,并且不能通过公钥反推出私钥。
  • 通过私钥加密的密文只能通过公钥能解密,通过公钥加密的密文也只能通过私钥能解密。

常见的非对称加密有 RSA、ESA、ECC 等。缺点:

  • 一次完全 TLS 握手,密钥交换时的非对称解密计算量占整个握手过程的 90% 以上。而对称加密的计算量只相当于非对称加密的 0.1%,如果应用层数据也使用非对称加解密,性能开销太大,无法承受。
  • 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。

摘要算法

所谓信息摘要,其实就是某种HASH算法。将信息明文转化为固定长度的字符。摘要算法有以下特性:

  • 只要源文本不同,计算得到的结果,必然不同(或者说机会很少)。
  • 无法从结果反推出源数据。

基于以上特性,我们一般使用摘要算法来校验原始内容是否被篡改。常见的摘要算法有 MD5、SHA 等。

证书

SSL证书根据验证级别,分为三种类型:

  • 域名型SSL证书,简称DVSSL;
  • 企业型SSL证书,简称OVSSL;
  • 增强型SSL证书,简称EVSSL。

除了验证级别维度的不同,统一级别的证书,它又根据保护域名的数量需求,SSL 证书又分为:

  • 单域名版:只保护一个域名,例如 www.abc.com 或者 login.abc.com 之类的单个域名
  • 多域名版:一张证书可以保护多个域名,例如同时保护 www.abc.com , www.bcd.com, pay.efg.com 等
  • 通配符版:一张证书保护同一个主域名下同一级的所有子域名,不限个数,形如 *.abc.com 。注意,通配符版只有 DVSSL 和 OVSSL 具有, EVSSL 不具有通配符版本。

细说 CA 和证书讲的比较详细。

什么是数字签名

数字签名就是用摘要算法(MD5、SHA等 )提取出源文件的摘要并用私钥进行加密后的内容。用于验证传输的内容是不是真实服务器发送的数据,发送的数据有没有被篡改过。

什么是证书

数字证书中包含了由某个受信任组织担保的用户或公司的相关信息,是为了解决“客户端”如何验证”服务端“提供的公钥是否是真的的问题。
数字证书里一般会包含公钥、公钥拥有者名称、CA 的数字签名、有效期、授权中心名称、证书序列号等信息。

什么是CA?

CA是Certificate Authority的缩写,也叫“证书授权中心”。(专业的解释看“这里”),负责管理和签发证书的第三方机构

为什么要证书

数字证书有两个作用:

  1. 身份授权。确保浏览器访问的网站是经过 CA 验证的可信任的网站。
  2. 分发公钥。每个数字证书都包含了注册者生成的公钥。在 SSL 握手时会通过 certificate 消息传输给客户端。

如何确认这个证书就是 CA 签发

答案就是数字签名(digital signature)。数字签名可以认为是一个证书的防伪标签,目前使用最广泛的 SHA-RSA 数字签名的制作和验证过程如下:

  • 数字签名的签发。首先是使用哈希函数对证书数据哈希,生成消息摘要,然后使用 CA 自己的私钥对证书内容和消息摘要进行加密
  • 数字签名的校验。使用 CA 的公钥解密签名,然后使用相同的签名函数对证书内容进行签名并和服务端的数字签名里的签名内容进行比较,如果相同就认为校验成功。

几点说明:

  • 数字签名签发和校验使用的密钥对是 CA 自己的公私密钥,跟证书申请者提交的公钥没有关系。
  • 数字签名的签发过程跟公钥加密的过程刚好相反,即是用私钥加密,公钥解密。
  • 现在大的 CA 都会有证书链,证书链的好处一是安全,保持根 CA 的私钥离线使用。第二个好处是方便部署和撤销,即如何证书出现问题,只需要撤销相应级别的证书,根证书依然安全。
  • CA 证书都是自签名, 即用自己的公钥和私钥完成了签名的制作和验证。而证书链上的证书签名都是使用上一级证书的密钥对完成签名和验证的
  • 怎样获取根 CA 和多级 CA 的密钥对?它们是否可信?当然可信,因为这些厂商跟浏览器和操作系统都有合作,它们的公钥都默认装到了浏览器或者操作系统环境里。比如 firefox 就自己维护了一个可信任的 CA 列表,而 chrome 和 IE 使用的是操作系统的 CA 列表。

客户端怎么验证证书

证书信任链机制

实际上,在HTTPS通信中,Server下发给Client的不仅仅是对端网站的证书,而是一个证书链。这个证书链是从网站证书开始,逐级往上,到根证书。每个证书都被下个证书的私钥签署,每个证书的 Issuer 就是下个证书的 Subject,root CA内置在浏览器中,是被浏览器所信任的。

参考:
大型网站的 HTTPS 实践(一)-- HTTPS 协议和原理
互联网安全之数字签名、数字证书与PKI系统

TLS(SSL)协议

HTTPS详细整理(干货)_第1张图片
TLS 协议主要有五部分:应用数据层协议,握手协议,报警协议,加密消息确认协议,心跳协议。TLS 协议本身又是由 record 协议传输的,record 协议的格式如上图最右所示。

ssl记录协议(SSL Record Protocol)

记录协议在客户机和服务器握手成功后使用,即客户机和服务器鉴别对方和确定安全信息交换使用的算法后,进入SSL记录协议,记录协议向SSL连接提供两个服务:
(1)保密性:使用握手协议定义的秘密密钥实现
(2)完整性:握手协议定义了MAC,用于保证消息完整性
为高层协议提供数据封装、压缩、加密等基本功能的支持。

SSL握手协议(SSL Handshake Protocol)

它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

具体过程

HTTPS详细整理(干货)_第2张图片
上图来自Https详解
HTTPS详细整理(干货)_第3张图片

客户端发出请求(ClientHello)

这一步,客户端主要向服务器提供以下信息:

(1) 支持的协议版本,比如TLS 1.0版。
(2) 一个客户端生成的随机数(Random1),稍后用于生成"对话密钥"(session key)。
(3) 支持的加密套件,比如RSA公钥加密。
(4) 支持的压缩方法。
(5) session ID (支持session的一般会有这个)
链接重用

TLS 握手阶段需要9次请求,非常耗时。链接重用目前有两种方式
session ID 会话复用

对于已经建立的SSL会话,使用session id为key(session id来自第一次请求的server hello中的session id字段),主密钥为value组成一对键值,保存在本地,服务器和客户端都保存一份。

当第二次握手时,客户端若想使用会话复用,则发起的client hello中session id会置上对应的值,服务器收到这个client hello,解析session id,查找本地是否有该session id,如果有,判断当前的加密套件和上个会话的加密套件是否一致,一致则允许使用会话复用,于是自己的server hello 中session id也置上和client hello中一样的值。然后计算对称秘钥,解析后续的操作。

如果服务器未查到客户端的session id指定的会话(可能是会话已经老化),则会重新握手,session id要么重新计算(和client hello中session id不一样),要么置成0,这两个方式都会告诉客户端这次会话不进行会话复用。
– 来自 TLS/SSL 协议详解 (22)会话复用

Session ticket会话复用

Session id会话复用有2个缺点:

  • 服务器会大量堆积会话,对服务器内存占用非常高。
  • 如果服务器是集群模式搭建,那么客户端和A各自保存的会话,在合B尝试会话复用时会失败。即服务器集群需要做Session id的同步。

Session ticket的工作流程如下:

  1. 客户端发起client hello,拓展中带上空的session ticket TLS,表明自己支持session ticket。

  2. 服务器在握手过程中,如果支持session ticket,则发送New session ticket类型的握手报文,其中包含了能够恢复包括主密钥在内的会话信息,当然,最简单的就是只发送master key。为了让中间人不可见,这个session ticket部分会进行编码、加密等操作。

  3. 客户端收到这个session ticket,就把当前的master key和这个ticket组成一对键值保存起来。服务器无需保存任何会话信息,客户端也无需知道session ticket具体表示什么。

  4. 当客户端尝试会话复用时,会在client hello的拓展中加上session ticket,然后服务器收到session ticket,回去进行解密、解码能相关操作,来恢复会话信息。如果能够恢复会话信息,那么久提取会话信息的主密钥进行后续的操作。

两者的主要区别,就是加密的握手记录谁负责保存的问题。Session ID 是服务端保存握手记录,Session Ticket 是 客户端保存握手记录。

服务器回应(SeverHello)

SeverHello包含以下内容:

(1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
(2) 一个服务器生成的随机数(Random2),稍后用于生成"对话密钥"(session key)。
(3) 确认使用的加密方法,比如RSA公钥加密。
(4) session ID

Certificate
服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥。

Server Key Exchange
仅用于(服务器)证书消息没有包含足够的信息来建立预置密钥(pre-master key)的情况。如短暂的DH算法,这里发送服务器使用的DH参数。RSA算法不需要这一步。

Certificate Request
服务端要求客户端上报证书,这一步是可选的,需要双向认证时要用到。

Server Hello Done
Server Hello Done 通知客户端 Server Hello 过程结束。

客户端回应

客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:

(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比
(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充
(7)此时浏览器就可以读取证书中的公钥(服务端的公钥),用于后续加密了。
(8)客户端再生成一个随机数 Random3,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。

至于为什么一定要用三个随机数,来生成"会话密钥",dog250解释得很好,总结来说就是为了增加随机性,不容易被暴力破解。SSL协议不信任每个主机都能生成完全随机的随机数。同时需要注意前两个随机数都是明文传输的,窃听者是可以轻易获取到的,只有最后一个 PreMaster Secret 是加密传输的,只有拥有服务器私钥才能解密,一旦 PreMaster Secret 泄露,那么本次通信就就完全可被破解了。

Client Key Exchange
上面客户端根据服务器传来的公钥生成了 pre-master Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密

Change Cipher Spec
这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。

Change Cipher Spec 有必要么?
Change Cipher Spec 用来通知对端,开始启用协商好的密钥做对称加密,内容只有1个字节。 这个协议是冗余的,在TLS 1.3里面直接被删除了。

Encrypted Handshake Message
这一步对应的是 Client Finish 消息,客户端将前面的握手消息生成摘要再用协商好的秘钥加密,这是客户端发出的第一条加密消息。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。

服务器的最后回应

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。

Change Cipher Spec
这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。

Encrypted Handshake Message
这一步对应的是 Server Finish 消息,服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。

总结 SSL/TLS协议的基本过程是这样的:

(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话密钥"(session key)。(只有双方知道,一共需要三个随机数)
(3) 双方采用"对话密钥"进行加密通信。(不直接用公钥加密,因为公钥加密计算量太大,服务器的公钥和私钥只用于加密和解密对话密钥(确切的来说是第三个随机数),无其他作用。) 关于随机数的介绍。

HTTPS详细整理(干货)_第4张图片
在SSL中会使用密钥交换算法交换密钥;使用密钥对数据进行加密;使用散列算法对数据的完整性进行验证,使用数字证书证明自己的身份。

https

不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。

(1) 窃听风险(eavesdropping):通信使用明文,可能会被第三方可以获知通信内容。
(2) 篡改风险(tampering):无法证明报文完整性,第三方可以修改通信内容。
(3) 冒充风险(pretending):不验证通信方的身份,第三方可以冒充他人身份参与通信。

SSL/TLS协议是为了解决这三大风险而设计的,希望达到:

(1) 所有信息都是加密传播,第三方无法窃听。
(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。
(3) 配备身份证书,防止身份被冒充。

https部署

golang 部署参考Go和HTTPS

curl模拟请求注意几点:

  • 如果要用生成server.csr设置CN域名访问,则需要在证书签名请求的时候在hosts中添加相应的ip映射
  • curl模拟请求的时候,单向认证用-k选项来跳过客户端对服务端证书的检测,即用
    curl -k https://localhost:8081,否则要加上--cacert RootCA.crt。双向认证时,除了跳过证书检查,还要加上客户端证书、私钥,证书编码需是pem格式。即curl -k --cert Client.pem --key Client.key https://localhost:8081

抓包工具原理

HTTPS详细整理(干货)_第5张图片
为什么客户端会通过抓包工具的验证?
抓包工具要成功抓取https的内容,首先需要在本地(客户端)安装抓包工具的根证书,这样,本地就认为抓包工具是合法的了(抓包工具的证书就能通过本地的验证)。

参考

SSL/TLS 握手过程详解
基于OpenSSL自建CA和颁发SSL证书
HTTPS 温故知新(三) —— 直观感受 TLS 握手流程(上)比较详细的介绍
HTTPS 温故知新(四) —— 直观感受 TLS 握手流程(下)

你可能感兴趣的:(网络)