什么是HTTPS

HTTPS 其实是一个“非常简单”的协议,RFC 文档很小,只有短短的 7 页,里面规定了新的协议名“https”,默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。

秘密就在于 HTTPS 名字里的“S”,它把 HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS,由“HTTP over TCP/IP”变成了“HTTP over SSL/TLS”,让 HTTP 运行在了安全的 SSL/TLS 协议,收发报文不再使用 Socket API,而是调用专门的安全接口。
image.png

SSL/TLS

SSL 即安全套接层(Secure Sockets Layer),在 OSI 模型中处于第 5 层(会话层),由网景公司于 1994 年发明,有 v2 和 v3 两个版本,而 v1 因为有严重的缺陷从未公开过。

SSL 发展到 v3 时已经证明了它自身是一个非常好的安全通信协议,于是互联网工程组 IETF 在 1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSL v3.1

目前应用的最广泛的 TLS 是 1.2,而之前的协议(TLS 1.1/1.0、SSL v3/v2)都已经被认为是不安全的,各大浏览器即将在 2020 年左右停止支持,所以接下来的讲解都针对的是 TLS1.2。

TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

浏览器和服务器在使用 TLS 建立连接时需要选择一组恰当的加密算法来实现安全通信,这些算法的组合被称为“密码套件”(cipher suite,也叫加密套件)。

协议 发布时间 状态
SSL 1.0 未公布 未公布
SSL 2.0 1995年 已于2011年弃用[2]
SSL 3.0 1996年 已于2015年弃用[3]
TLS 1.0 1999年 于2021年弃用[4]
TLS 1.1 2006年 于2021年弃用[4]
TLS 1.2 2008年
TLS 1.3 2018年

wikipedia

对称加密与非对称加密

对称加密

image.png
TLS 里有非常多的对称加密算法可供选择,比如 RC4、DES、3DES、AES、ChaCha20 等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有 AES ChaCha20

AES 的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。

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

对称算法还有一个“分组模式”的概念,它可以让算法用固定长度的密钥加密任意长度的明文,把小秘密(即密钥)转化为大秘密(即密文)

最新的分组模式被称为 AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305。

把上面这些组合起来,就可以得到 TLS 密码套件中定义的对称加密算法。

比如,AES128-GCM,意思是密钥长度为 128 位的 AES 算法,使用的分组模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 算法,使用的分组模式是 Poly1305。

非对称加密

image.png

它有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,“不对称”,公钥可以公开给任何人使用,而私钥必须严格保密。

公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。

非对称加密算法的设计要比对称算法难得多,在 TLS 里只有很少的几种,比如 DH、DSA、RSAECC 等。

混合加密

image.png
对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。

数字签名与证书

摘要算法

实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。
image.png
你一定在日常工作中听过、或者用过 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。
目前 TLS 推荐使用的是 SHA-1 的后继者:SHA-2。
SHA-2 实际上是一系列摘要算法的统称,总共有 6 种,常用的有 SHA224、SHA256、SHA384,分别能够生成 28 字节、32 字节、48 字节的摘要

完整性

摘要算法保证了“数字摘要”和原文是完全等价的。所以,我们只要在原文后附上它的摘要,就能够保证数据的完整性。不过摘要算法不具有机密性,如果明文传输,那么黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。

所以,真正的完整性必须要建立在机密性之上,在混合加密系统里用会话密钥加密消息摘要,这样黑客无法得知明文,也就没有办法动手脚了。
image.png

数字签名

加密算法结合摘要算法,我们的通信过程可以说是比较安全了。但这里还有漏洞,就是通信的两个端点(endpoint)。

现实生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,就能够证明这份文件确实是由本人而不是其他人发出的。

没错,这个东西就是非对称加密里的“私钥”,使用私钥再加上摘要算法,就能够实现“数字签名”,同时实现“身份认证”和“不可否认”。

数字签名的原理其实很简单,就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密。

但又因为非对称加密效率太低,所以私钥只加密原文的摘要,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输。

签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的。

刚才的这两个行为也有专用术语,叫做“签名”和“验签”。

只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

比如,你用自己的私钥签名一个消息“我是小明”。网站收到后用你的公钥验签,确认身份没问题,于是也用它的私钥签名消息“我是某宝”。你收到后再用它的公钥验一下,也没问题,这样你和网站就都知道对方不是假冒的,后面就可以用混合加密进行安全通信了。

HTTPS - 图8

数字证书和 CA

这个“第三方”就是我们常说的CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。

CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)。

知名的 CA 全世界就那么几家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们签发的证书分 DV、OV、EV 三种,区别在于可信程度。

DV 是最低的,只是域名级别的可信,背后是谁不知道。EV 是最高的,经过了法律和审计的严格核查,可以证明网站

CA 怎么证明自己呢?
这还是信任链的问题。小一点的 CA 可以让大 CA 签名认证,但链条的最后,也就是Root CA,就只能自己证明自己了,这个就叫“自签名证书”(Self-Signed Certificate)或者“根证书”(Root Certificate)。你必须相信,否则整个证书信任链就走不下去了。

证书体系(PKI,Public Key Infrastructure)虽然是目前整个网络世界的安全基础设施,但绝对的安全是不存在的,它也有弱点,还是关键的“信任”二字。

如果 CA 失误或者被欺骗,签发了错误的证书,虽然证书是真的,可它代表的网站却是假的。

还有一种更危险的情况,CA 被黑客攻陷,或者 CA 有恶意,因为它(即根证书)是信任的源头,整个信任链里的所有证书也就都不可信了。

中间人攻击

image.png
假设 A 希望与 B 通 信。同时,M 希望拦截窃会话以进行窃听并可能在某些时候传送给B一个虚假的消息。

首先,A 会向 B索取他的公钥。如果 B 将他的公钥发送给A,并且此时 M 能够拦截到这个公钥,就可以实施中间人攻击。M 发送给 A一个伪造的消息,声称自己是B ,并且附上了 M 自己的公钥(而不是 B 的)。

A 收到公钥后相信这个公钥是 B 的,于是 A 将她的消息用 M 的公钥加密,并将加密后的消息回给 B。M 再次截获 A 回给 B 的消息,并使用 M 自己的私钥对消息进行解密。如果M愿意,她也可以对消息进行修改,然后 M 使用 B 原先发给 A 的公钥对消息再次加密。当 B 收到新加密后的消息时,他会相信这是从 A 那里发来的消息。

传输过程⭐

大体过程

  1. 服务端生成网站的公钥和私钥,然后向CA机构申请自己数字证书(包含被CA的私钥加密过的网站的公钥)
  2. 客户端请求数字证书,拿到之后用 CA的公钥(已存在客户端上的)解密和验证签名,获取到网站的公钥)
  3. 客户端生成一个会话密钥,使用网站的公钥对其加密,发送给服务端。
  4. 服务端收到会话密钥并解密后,之后用这个会话密钥进行对称加密传递报文。

    关于会话密钥的生成规则,第3、4步可能不太对,大体可以先这么理解,后文有具体细节。

HTTPS - 图10

下面的这张图简要地描述了 TLS 的握手过程,其中每一个“框”都是一个记录,多个记录组合成一个 TCP 包发送。所以,最多经过两次消息往返(2个RTT,4 个消息)就可以完成握手,然后就可以在安全的通信环境里发送 HTTP 报文,实现 HTTPS 协议。
image.png
不同的密钥交换算法,TLS 的握手过程可能会有一些区别。HTTPS 常用的密钥交换算法有两种,分别是 RSA ECDHE 算法。
密钥交换算法:为考虑到性能的问题,所以双方在加密应用信息时使用的是对称加密密钥,而对称加密密钥是不能被泄漏的,为了保证对称加密密钥的安全性,所以使用非对称加密的方式来保护对称加密密钥的协商

ECDHE 握手过程

  1. 先TCP三次握手
  2. 然后客户端向服务端发送Client Hello的消息,进行打招呼。
    1. 客户端支持的TLS版本号
    2. 随机数(Client Random)
    3. 支持的密码套件 ```http Handshake Protocol: Client Hello Version: TLS 1.2 (0x0303)
      Random: 1cbf803321fd2623408dfe… Cipher Suites (17 suites) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
  1. 3. 服务端收到消息后,返回一个`Server Hello`的消息(对上TLS的版本和选择密码套件),并发送数字证书。
  2. 1. TLS的版本号
  3. 2. **随机数(Server Random)**
  4. 3. 选择使用的密码套件
  5. ```http
  6. Handshake Protocol: Server Hello
  7. Version: TLS 1.2 (0x0303)
  8. Random: 0e6320f21bae50842e96…
  9. Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
  1. 服务端发送证书后,接着会发送Server Key Exchange消息,里面是椭圆曲线的参数(Server Params)

    1. Handshake Protocol: Server Key Exchange
    2. EC Diffie-Hellman Server Params
    3. Curve Type: named_curve (0x03)
    4. Named Curve: x25519 (0x001d)
    5. Pubkey: 3b39deaf00217894e...
    6. Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
    7. Signature: 37141adac38ea4...
  2. 之后发送Server Hello Done消息,表示服务端发送完毕。

  3. 客户端按照密码套件的要求,也生成一个椭圆曲线的参数(Client Params),用Client Key Exchange消息发给服务器。

  4. 户端和服务端都有了Client Params和Server Params,生成随机数(pre Master),再加上之前两个随机,生成主密钥(master secret),再派生出会话密钥。
  5. 有主密钥和派生的会话密钥,握手就快结束了。客户端发一个Change Cipher Spec,然后再发一个Finished消息,把之前所有发送的数据做个摘要,再加密一下,让服务器做个验证。
  6. 服务器也是同样的操作,发Change Cipher SpecFinished消息,双方都验证加密解密 OK,握手正式结束,后面就收发被加密的 HTTP 请求和响应了。

RSA 握手过程

和ECDHE不同的是:

  • 使用 ECDHE 实现密钥交换,会在服务器端发出“Server Key Exchange”消息(椭圆曲线的参数)。
  • 使用 ECDHE,客户端可以不用等到服务器发回“Finished”确认握手完毕,立即就发出 HTTP 报文,省去了一个消息往返的时间浪费。这个叫“TLS False Start”,意思就是“抢跑”。
  • RSA 的 Pre-Master不是由算法生成,而是客户端直接生成随机数,然后用服务器的公钥加密,通过“Client Key Exchange”消息发给服务器(不具有前向保密性)。服务器再用私钥解密,这样双方也实现了共享三个随机数,就可以生成主密钥。

重点:

  1. HTTPS 协议会先与服务器执行 TCP 握手,然后执行 TLS 握手,才能建立安全连接;
  2. 握手的目标是安全地交换对称密钥,需要三个随机数,第三个随机数“Pre-Master”必须加密传输,绝对不能让黑客破解;
  3. “Hello”消息交换随机数,“Key Exchange”消息交换“Pre-Master”;
  4. “Change Cipher Spec”之前传输的都是明文,之后都是对称密钥加密的密文。

TLS.png
左RSA,右ECDHE

极客时间-透视http协议 【一听就懂】https机制原理 图解 HTTPS https://blog.csdn.net/qq_41083105/article/details/116207341 图解 ECDHE 密钥交换算法