计算机网络-HTTPS

297 阅读14分钟

1. HTTPS为什么出现

HTTPS协议是Hyper Text Transfer Protocol over SecureSocket Layer(超文本传输安全协议)的缩写,是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。

HTTPS 是 HTTP 协议的一种扩展,它本身并不保传输的证安全性,那么谁来保证安全性呢?在 HTTPS 中,使用传输层安全性(TLS)安全套接字层(SSL)对通信协议进行加密。也就是 HTTP + SSL(TLS) = HTTPS

image.png

1.1 HTTPS解决了什么问题?

一个简单的回答可能会是 HTTP 它不安全。

  • 由于 HTTP 天生明文传输的特性,在 HTTP 的传输过程中,任何人都有可能从中截获、修改或者伪造请求发送,所以可以认为 HTTP 是不安全的,信息容易被窃取
  • 在 HTTP 的传输过程中不会验证通信方的身份,因此 HTTP 信息交换的双方可能会遭到伪装,也就是没有用户验证,身份容易被伪装
  • 在 HTTP 的传输过程中,接收方和发送方并不会验证报文的完整性,信息容易被篡改

1.2 HTTPS做了什么?

HTTPS 协议提供了三个关键的指标:

  • 信息加密: HTTP 交互信息是被加密的,第三⽅就⽆法被窃取;
  • 校验机制:校验信息传输过程中是否有被第三⽅篡改过,如果被篡改过,则会有警告提示;
  • 身份证书:证明淘宝是真的淘宝⽹;

image.png

2. 密码学/数字证书

在了解HTTPS的整个流程前我们先来学习一些密码学和数字证书相关的知识点。

2.1 对称加密

在了解对称加密前,我们先来了解一下密码学的东西,在密码学中,有几个概念:明文、密文、加密、解密.

  • 明文(Plaintext):一般认为明文是有意义的字符或者比特集,或者是通过某种公开编码就能获得的消息。明文通常用 m 或 p 表示。

  • 密文(Ciphertext):对明文进行某种加密后就变成了密文。

  • 加密(Encrypt):把原始的信息(明文)转换为密文的信息变换过程。

  • 解密(Decrypt):把已经加密的信息恢复成明文的过程。

对称加密 (Symmetrical Encryption) 顾名思义就是指加密和解密时使用的密钥都是同样的密钥。只要保证了密钥的安全性,那么整个通信过程也就是具有了机密性。

image.png

TLS 里面有比较多的加密算法可供使用,比如 DES、3DES、AES、ChaCha20、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK 等。目前最常用的是 AES-128, AES-192、AES-256 和 ChaCha20

AES-128, AES-192 和 AES-256 都是属于 AES ,AES 的全称是Advanced Encryption Standard(高级加密标准),它是 DES 算法的替代者,安全强度很高,性能也很好,是应用最广泛的对称加密算法

ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错算法。

(其它可自行搜索)

2.2 非对称加密

非对称加密(Asymmetrical Encryption) 也被称为公钥加密,相对于对称加密来说,非对称加密是一种新的改良加密方式。密钥通过网络传输交换,它能够确保及时密钥被拦截,也不会暴露数据信息。

非对称加密中有两个密钥,一个是公钥,一个是私钥,公钥进行加密,私钥进行解密。公开密钥可供任何人使用,私钥只有你自己能够知道

image.png

公钥加密的文本只能使用私钥解密,同时使用私钥加密的文本也可以使用公钥解密。公钥不需要具有安全性,因为公钥需要在网络间进行传输,非对称加密可以解决密钥交换的问题。

网站保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文。

其中 RSA 加密算法是最重要的、最出名的一个了。例如 DHE_RSA_CAMELLIA128_GCM_SHA256。它的安全性基于 整数分解,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。

TLS 是使用对称加密非对称加密 的混合加密方式来实现机密性。

2.3 混合加密

RSA 的运算速度非常慢,而 AES 的加密速度比较快,而 TLS 正是使用了这种混合加密方式。

在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE ,首先解决密钥交换的问题。

然后用随机数产生对称算法使用的会话密钥(session key),再用公钥加密。对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换。

image.png

使用混合加密的方式实现了机密性,是不是就能够安全的传输数据了呢?还不够,在机密性的基础上还要加上完整性身份认证的特性,才能实现真正的安全。而实现完整性的主要手段是 摘要算法(Digest Algorithm).

2.4 了解HASH算法

Hash算法,也叫做散列算法,就是把任意长度的输入通过散列函数变化成固定长度的输出,该输出就是散列值。可以用来以一种较短的信息来标识输入信息的唯一性。常见的Hash算法有MD5、SHA1。

Hash算法特点:

正向快速:给定指定明文和Hash算法,能在有限资源和时间内计算输出散列值。

逆向困难:在有限时间内,基本不可能推断出明文。

输入敏感:明文的微小变动,产生的散列值区别非常大。

2.4 数字证书/签名

黑客伪装成你,来向服务器发送信息,也可以伪装称为服务器,接受你发送的信息。那么怎么解决这个问题呢?

如何确定你自己的唯一性呢?我们在上面的叙述过程中出现过公钥加密,私钥解密的这个概念。提到的私钥只有你一个人所有,能够辨别唯一性,所以我们可以把顺序调换一下,变成私钥加密,公钥解密。使用私钥再加上摘要算法,就能够实现数字签名,从而实现认证

个数字证书通常包含了:

  1. 公钥;

  2. 持有者信息;

  3. 证书认证机构(CA)的信息;

  4. CA 对这份⽂件的数字签名及使⽤的算法;

  5. 证书有效期;

  6. 还有⼀些其他额外信息

我们⽤证书来认证公钥持有者的身份(服务端的身份),那证书⼜是怎么来的?⼜该怎么认证证书呢?

为了让服务端的公钥被⼤家信任,服务端的证书都是由 CA (Certificate Authority,证书认证机构)签名的,CA 就是⽹络世界⾥的公安局、公证中⼼,具有极⾼的可信度,所以由它来给各个公钥签名,信任的⼀⽅签发的证书, 那必然证书也是被信任的。

之所以要签名,是因为签名的作⽤可以避免中间⼈在获取证书时对证书内容的篡改。

数字证书签发和验证流程:

image.png

  • CA 签发证书的过程,如上图左边部分:
  1. ⾸先 CA 会把持有者的公钥、⽤途、颁发者、有效时间等信息打成⼀个包,然后对这些信息进⾏ Hash 计算, 得到⼀个 Hash 值;
  2. 然后 CA 会使⽤⾃⼰的私钥将该 Hash 值加密,⽣成 Certificate Signature,也就是 CA 对证书做了签名;
  3. 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书;
  • 客户端校验服务端的数字证书的过程,如上图右边部分:
  1. ⾸先客户端会使⽤同样的 Hash 算法获取该证书的 Hash 值 H1;
  2. 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使⽤ CA 的公钥解密 Certificate Signature 内容,得到⼀个 Hash 值 H2 ;
  3. 最后⽐较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

3. 探究HTTPS

经过上面的学习你基本上已经学习到了https的精髓了。

传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的,在将 TLS 证书部署服务端时,证书⽂件中包含⼀对公私钥,其中公钥会在 TLS 握⼿阶段传递给客户端,私钥则⼀直留在服务端,⼀定要确保私钥不能被窃取。

在 RSA 密钥协商算法中,客户端会⽣成随机密钥,并使⽤服务端的公钥加密后再传给服务端根据⾮对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双⽅就得到了相同的密钥,再⽤它加密应⽤消息。

⽤ Wireshark ⼯具抓了⽤ RSA 密钥交换的 TLS 握⼿过程,你可以从下⾯看到,⼀共经历来四次握⼿:

image.png

3.1 TLS第一次握手

客户端⾸先会发⼀个「Client Hello」消息,字⾯意思我们也能理解到,这是跟服务器「打招呼」。

image.png

消息⾥⾯有客户端使⽤的 TLS 版本号、⽀持的密码套件列表,以及⽣成的随机数(Client Random),这个随机 数会被服务端保留,它是⽣成对称加密密钥的材料之⼀。

3.2 TLS第二次握手

当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否⽀持,和从密码套件列表中选择⼀个密码 套件,以及⽣成随机数(Server Random)。

返回「Server Hello」消息,消息⾥⾯有服务器确认的 TLS 版本号,也给出了随机数(Server Random), 然后从客户端的密码套件列表选择了⼀个合适的密码套件

image.png

服务端选择的密码套件是 Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256, 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法

  • 服务端为了证明⾃⼰的身份,会发送「Server Certificate」给客户端,这个消息⾥含有数字证书。

image.png

  • 随后,服务端发了「Server Hello Done」消息,⽬的是告诉客户端,我已经把该给你的东⻄都给你了,本次打招 呼完毕。

image.png

3.3 客户端验证证书

在这⾥刹个⻋,客户端拿到了服务端的数字证书后,要怎么校验该数字证书是真实有效的呢?

在说校验数字证书是否可信的过程前,我们先来看看数字证书是什么?

⼀个数字证书通常包含了:

  1. 公钥;
  2. 持有者信息;
  3. 证书认证机构(CA)的信息;
  4. CA 对这份⽂件的数字签名及使⽤的算法;
  5. 证书有效期;
  6. 还有⼀些其他额外信息;

那数字证书的作⽤,是⽤来认证公钥持有者的身份,以防⽌第三⽅进⾏冒充。说简单些,证书就是⽤来告诉客户 端,该服务端是否是合法的,因为只有证书合法,才代表服务端身份是可信的

我们⽤证书来认证公钥持有者的身份(服务端的身份),那证书⼜是怎么来的?⼜该怎么认证证书呢?

为了让服务端的公钥被⼤家信任,服务端的证书都是由 CA (Certificate Authority,证书认证机构)签名的,CA 就是⽹络世界⾥的公安局、公证中⼼,具有极⾼的可信度,所以由它来给各个公钥签名,信任的⼀⽅签发的证书, 那必然证书也是被信任的。

之所以要签名,是因为签名的作⽤可以避免中间⼈在获取证书时对证书内容的篡改

数字证书签发和验证流程:

image.png

  • CA 签发证书的过程,如上图左边部分:
  1. ⾸先 CA 会把持有者的公钥、⽤途、颁发者、有效时间等信息打成⼀个包,然后对这些信息进⾏ Hash 计算, 得到⼀个 Hash 值;
  2. 然后 CA 会使⽤⾃⼰的私钥将该 Hash 值加密,⽣成 Certificate Signature,也就是 CA 对证书做了签名;
  3. 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书;
  • 客户端校验服务端的数字证书的过程,如上图右边部分:
  1. ⾸先客户端会使⽤同样的 Hash 算法获取该证书的 Hash 值 H1;
  2. 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使⽤ CA 的公钥解密 Certificate Signature 内容,得到⼀个 Hash 值 H2 ;
  3. 最后⽐较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

3.4 TLS第三次握手

客户端验证完证书后,认为可信则继续往下⾛。接着,客户端就会⽣成⼀个新的随机数 (pre-master),⽤服务器 的 RSA 公钥加密该随机数,通过「Change Cipher Key Exchange」消息传给服务端

image.png

服务端收到后,⽤ RSA 私钥解密,得到客户端发来的随机数 (pre-master)。

客户端和服务端双⽅都共享了三个随机数,分别是 Client Random、Server Random、pre-master。 于是,双⽅根据已经得到的三个随机数,⽣成会话密钥(Master Secret),它是对称密钥,⽤于对后续的 HTTP 请求/响应的数据加解密.

  • ⽣成完会话密钥后,然后客户端发⼀个「Change Cipher Spec」,告诉服务端开始使⽤加密⽅式发送消息

image.png

  • 客户端再发⼀个「Encrypted Handshake Message(Finishd)」消息,把之前所有发送的数据做个摘 要,再⽤会话密钥(master secret)加密⼀下,让服务器做个验证,验证加密通信是否可⽤和之前握⼿信息是否有 被中途篡改过 image.png

可以发现,「Change Cipher Spec」之前传输的 TLS 握⼿数据都是明⽂,之后都是对称密钥加密的密⽂。

3.5 TLS第四次握手

服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双⽅都 验证加密和解密没问题,那么握⼿正式完成。

最后,就⽤「会话密钥」加解密 HTTP 请求和响应了。

4. HTTPS的优化点

因为 HTTPS 相⽐ HTTP 协议多⼀个 TLS 协议握⼿过程,⽬的是为了通过⾮对称加密握⼿协商或者交换出对称加密 密钥,这个过程最⻓可以花费掉 2 RTT,接着后续传输的应⽤数据都得使⽤对称加密密钥来加密/解密。

image.png

  • 对于协议优化的⽅向:
  1. 密钥交换算法应该选择 ECDHE 算法,⽽不⽤ RSA 算法,因为 ECDHE 算法具备前向安全性,⽽且客户端可 以在第三次握⼿之后,就发送加密应⽤数据,节省了 1 RTT。
  2. 将 TSL1.2 升级 TSL1.3,因为 TSL1.3 的握⼿过程只需要 1 RTT,⽽且安全性更强。
  • 对于证书优化的⽅向:
  1. 服务器应该选⽤ ECDSA 证书,⽽⾮ RSA 证书,因为在相同安全级别下,ECC 的密钥⻓度⽐ RSA 短很多,这 样可以提⾼证书传输的效率;
  2. 服务器应该开启 OCSP Stapling 功能,由服务器预先获得 OCSP 的响应,并把响应结果缓存起来,这样 TLS 握⼿的时候就不⽤再访问 CA 服务器,减少了⽹络通信的开销,提⾼了证书验证的效率;
  • 对于重连 HTTPS 时,我们可以使⽤⼀些技术让客户端和服务端使⽤上⼀次 HTTPS 连接使⽤的会话密钥,直接恢 复会话,⽽不⽤再重新⾛完整的 TLS 握⼿过程。
  • 常⻅的会话重⽤技术有 Session ID 和 Session Ticket,⽤了会话重⽤技术,当再次重连 HTTPS 时,只需要 1 RTT 就可以恢复会话。对于 TLS1.3 使⽤ Pre-shared Key 会话重⽤技术,只需要 0 RTT 就可以恢复会话。

这些会话重⽤技术虽然好⽤,但是存在⼀定的安全⻛险,它们不仅不具备前向安全,⽽且有重放攻击的⻛险,所以 应当对会话密钥设定⼀个合理的过期时间