【Security】HTTPS

Posted by 西维蜀黍 on 2019-05-13, Last Modified on 2024-01-16

协议历史

SSL(Secure Sockets Layer)协议由Netscape公司开发,历史可以追溯到Netscape Navigator浏览器统治互联网的时代。SSL 1.0 从未发布过,因为存在严重的安全漏洞。

SSL 2.0的开发基本上没有与Netscape以外的安全专家进行过商讨,所以有严重的弱点,被认为是失败的协议,最终退出了历史的舞台。这次失败使Netscape专注于SSL 3.0,并于1995年年底发布。 虽然名称与早先的协议版本相同,但SSL 3.0是完全重新设计的协议。SSL 3.0 在Web上获得了广泛的应用。

1996年5月,TLS工作组开始将SSL从Netscape迁移至IETF。由于Microsoft和Netscape 当时正在为Web的统治权争得不可开交,整个迁移过程进行得非常缓慢、艰难。最终,TLS 1.0 于1999年1月问世,见RFC 2246。事实上,TLS 1.0与SSL 3的差异并不大。

直到2006年4月,下一个版本TLS 1.1才问世,仅仅修复了一些关键的安全问题。然而,协议的重要更改是作为TLS扩展于2003年6月发布的,并被集成到了协议中,这比大家的预期早了好几年。

2008年8月,TLS 1.2发布。该版本添加了对已验证加密的支持,并且基本上删除了协议说明中所有硬编码的安全基元,使协议完全弹性化。

TLS 1.3在 RFC 8446 中定义,于2018年8月发表。

SSL 3.0存在的安全性问题

2014年10月,Google发布在SSL 3.0中发现设计缺陷,建议禁用此一协议。攻击者可以向TLS发送虚假错误提示,然后将安全连接强行降级到过时且不安全的SSL 3.0,然后就可以利用其中的设计漏洞窃取敏感信息。Google在自己公司相关产品中陆续禁止回溯兼容,强制使用TLS协议。Mozilla也在11月25日发布的Firefox 34中彻底禁用了SSL 3.0。微软同样发出了安全通告[6]。

什么是 HTTPS

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

HTTP 与 HTTPS 的区别

  • HTTP 是明文传输,HTTPS 通过 SSL\TLS 进行了加密
  • HTTP 的端口号是 80,HTTPS 是 443
  • HTTPS 需要到 CA 申请证书,一般免费证书很少,需要交费
  • HTTPS 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。

为什么要使用 HTTPS

其实使用 HTTPS 最主要的用处是以下两点:

  • 建立一个信息安全通道,来保证数据传输的安全
  • 确认网站的真实性,防止钓鱼网站

HTTPS 如何防止中间人攻击

Refer to https://swsmile.info/post/security/evolve-secured-http/

TLS, SSL 和 HTTPS的关系

  1. SSL和TLS
    • SSL和TLS都是加密协议,用于在网络上提供安全的数据传输。如前所述,TLS实际上是SSL的后继者,提供了更强的安全性和更现代的加密技术。
  2. HTTPS
    • HTTPS,即HTTP over SSL/TLS,是一种用于安全网络通信的协议。
    • 它基于HTTP(超文本传输协议),但通过SSL或TLS来加密数据包,从而保护数据传输过程中的数据免受窃听和篡改。
  3. 关系
    • 在早期,HTTPS是通过SSL实现加密的,但随着时间的推移和技术的发展,TLS逐渐取代了SSL成为HTTPS的加密基础。
    • 现在,当我们谈论HTTPS和其加密时,实际上是在指TLS,尽管“SSL”这个术语仍然被广泛使用。
  4. 使用场景
    • 在浏览器中,当你访问一个以“https://”开头的网站时,你的浏览器和该网站之间的通信是通过TLS加密的(即使有时仍然被称为SSL加密)。
    • 这种加密保护了你的敏感数据,如登录凭据、信用卡信息和个人信息,不被中间人攻击或窃听。

总结一下,HTTPS是用于安全网络通信的协议,而SSL和TLS是实现这种通信安全的加密协议。TLS是SSL的更新和更安全的版本,现在是HTTPS加密的标准方法。

TLS的通信过程

握手(Handshake)阶段

Client-hello 阶段

浏览器中完成地址输入后,解析域名获得 IP Host 地址, 浏览器会与此 Host 的443(默认, 如果指定其他端口则会连接此端口)尝试连接, 也就是 TLS 握手协议的 Client-hello。

浏览器会将"支持的加密组件"、随机数等信息发送给服务器, 并会附上一份随机生成的 session ticket1。

Server-hello 阶段

服务器收到浏览器发送来的 TLS 握手请求后,存储浏览器发送的session ticket 1, 并返回服务器与浏览器妥协(两方均支持)的加密套件方法、随机数和随机生成的 session ticket 2 提供给浏览器。

Certificate 阶段

服务器根据发送来的 host 寻找对于的服务器证书, 然后会将服务器证书返回给浏览器。

Server Hello Done 阶段

Cipher-spec Exchange阶段

浏览器收到服务器返回的证书后,会验证证书有效性。验证步骤大概如下:

  • 验证证书有效期(起止时间);
  • 验证证书域名(与浏览器地址栏中域名是否匹配);
  • 验证证书吊销状态(CRL+OCSP);
  • 验证证书颁发机构, 如果颁发机构是中间证书, 在验证中间证书的有效期/颁发机构/吊销状态。 一直验证到最后一层证书, 如果最后一层证书是在操作系统或浏览器内置, 那么就是可信的, 否则就是自签名。

以上验证步骤, 需要全部通过。 否则就会显示警告

若对数字证书的有效性检查通过,则随机生成一份 session ticket 3 (称为预主密钥,Premaster Secret,这是浏览器生成的第二份 session ticket)

其中session ticket 1 由浏览器生成,session ticket 2由服务器生成)。

浏览器用 session ticket 1 + session ticket 2 + session ticket 3 ,生成 session key (即主密钥,master secret)。并通过使用证书中的公钥,用协商确定的特定"秘钥交换算法"对session ticket 3进行加密,提供给服务器。

服务器收到这个加密后的session ticket 3 后, 用自己的私钥, 解密出 session ticket 3。

然后用 session ticket 1 + session ticket 2 + session ticket 3 ,也生成 session key(即主密钥,master secret)。这个session key 就是在真正的数据传输阶段,进行对称加密传输时使用的秘钥。

显然,由于只有服务器才有私钥(不考虑服务器的私钥被泄露的情况),所以只有服务器才能得到正确的 session ticket 3,最终生成正确的 session key,最终保证了即使中间攻击人拿到了加密后的session ticket 3,也无法生成session key(在真正的数据传输阶段,进行对称加密传输时使用的秘钥),所以无法看到进行真正数据传输时的数据内容。

总结来说,

  1. 服务器与浏览器在HTTPS握手完成后最终使用的对称加密秘钥,即 session key(即主密钥,master secret)
  2. session key通过session ticket 1 + session ticket 2 + session ticket 3 生成
  3. 其中session ticket 1 和 session ticket 2通过明文传输;而session ticket 3由浏览器生成,并使用数字证书的公钥对其进行加密后,传输给服务器。

数据传输阶段

在握手(Handshake)阶段和Cipher-spec Exchange阶段完成之后,就进入真正的数据传输阶段。

可能有人会问,既然 TLS 证书中已经内置了公钥了,为什么还在数据传输阶段还需要使用使用对称加密。

其实,因为非对称加密非常消耗 CPU,所以只有在协商秘钥时候使用非对称加密, 而应用层数据交换时,就用协商成功的秘钥作为私钥对称加密传输。

TLS 证书

证书链

  • 客户端在获取到了站点证书的同时,也拿到了站点的公钥;
  • 客户端要验证证书中站点的公钥,本质上是在验证证书本身;
  • 在站点证书中,获取颁发者(CA)名称;
  • 通过该颁发者(CA)名称,找到对应的颁发者中间证书;
  • 再通过颁发者中间证书向上回溯,找到认证中间证书商的源头证书颁发者(根证书颁发机构)。由于源头的证书颁发者非常少,浏览器默认内置了这些根证书颁发机构证书;
  • 通过根证书颁发机构证书内置的公钥,可以验证根证书颁发机构证书自身的可信性;
  • 继而,通过根证书颁发机构证书内置的公钥,可以验证根证书颁发机构认证的中间证书的可信性;
  • 继而,通过中间证书内置的公钥,可以验证站点证书的可信性。

证书分类

证书分为DV(Digital Verification),OV(Organization Verification)和EV(Extended Verification)s,其中EV证书最贵,可以在浏览器中看到绿色的就是EV证书。证书从申请到批准要走很久的流程,需要提供很多的公司认证信息和个人信息,否则是不会通过的。因此可以保证签发的证书内容是可信的。

TLS 的子协议

TLS的主规格说明书定义了四个核心子协议:握手协议(handshake protocol)、密钥规格变更协议(change cipher spec protocol)、应用数据协议(application data protocol)和警报协议(alert protocol)。

握手协议(handshake protocol)

ClientHello

在一次新的握手流程中,ClientHello消息总是第一条消息。这条消息将客户端的功能和首 选项传送给服务器。客户端会在新建连接后,希望重新协商或者响应服务器发起的重新协商请求 (由HelloRequest消息指示)时,发送这条消息。

在下面的例子中,你可以观察到ClientHello消息。为了更简洁,我减少了一些信息展示, 但是包含了所有的关键元素。

Handshake protocol: ClientHello

	Version: TLS 1.2 
	Random 
		Client time: May 22, 2030 02:43:46 GMT 
		Random bytes: b76b0e61829557eb4c611adfd2d36eb232dc1332fe29802e321ee871 
	Session ID: (empty) 
	Cipher Suites 
		Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
		Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
		Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 
		Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
		Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
		Suite: TLS_RSA_WITH_AES_128_CBC_SHA 
		Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA 
		Suite: TLS_RSA_WITH_RC4_128_SHA 
	Compression methods 
		Method: null 
	Extensions 
		Extension: server_name 
			Hostname: www.feistyduck.com 
		Extension: renegotiation_info 
		Extension: elliptic_curves 
			Named curve: secp256r1 
			Named curve: secp384r1 
		Extension: signature_algorithms 
			Algorithm: sha1/rsa 
			Algorithm: sha256/rsa 
			Algorithm: sha1/ecdsa 
			Algorithm: sha256/ecdsa

可以看到,绝大多数消息字段光看名称就很容易理解,而且消息的结构也很容易理解。

  • Version:协议版本(protocol version)指示客户端支持的最佳协议版本。
  • Random:随机数(random)字段包含32字节的数据。当然,只有28字节是随机生成的;剩余的4字 节包含额外的信息,受客户端时钟的影响。准确来说,客户端时间与协议不相关,而且 协议规格文档中言及此事时也很清楚(“基本的TLS协议不需要正确设置时钟,更高层或 应用协议可以定义额外的需求项。”);该字段是1994年在Netscape Navigator中发现了一个 严重故障之后,为了防御弱随机数生成器而引入的 。尽管这个字段曾经一直含有精确时 间的部分,但现在仍然有人担心客户端时间可能被用于大规模浏览器指纹采集,或者简单地发 送随机的4字节。 在握手时,客户端和服务器都会提供随机数。这种随机性对每次握手都是独一无二的,在 身份验证中起着举足轻重的作用。它可以防止重放攻击,并确认初始数据交换的完整性。
  • Session ID:在第一次连接时,会话ID(session ID)字段是空的,这表示客户端并不希望恢复某个已 存在的会话。在后续的连接中,这个字段可以保存会话的唯一标识。服务器可以借助会 话ID在自己的缓存中找到对应的会话状态。典型的会话ID包含32字节随机生成的数据, 这些数据本身并没有什么价值。
  • Cipher Suites:密码套件(cipher suite)块是由客户端支持的所有密码套件组成的列表,该列表是按优先 级顺序排列的。
  • Compression:客户端可以提交一个或多个支持压缩的方法。默认的压缩方法是null,代表没有压缩。
  • Extensions:扩展(extension)块由任意数量的扩展组成。这些扩展会携带额外数据。ServerHello

ServerHello

消息的意义是将服务器选择的连接参数传送回客户端。 这个消息的结构与 ClientHello类似,只是每个字段只包含一个选项。

Handshake protocol: ServerHello
	Version: TLS 1.2 
	Random
		Server time: Mar 10, 2059 02:35:57 GMT
		Random bytes: 8469b09b480c1978182ce1b59290487609f41132312ca22aacaf5012 
	Session ID: 4cae75c91cf5adf55f93c9fb5dd36d19903b1182029af3d527b7a42ef1c32c80 
	Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 
	Compression method: null 
	Extensions
		Extension: server_name 
		Extension: renegotiation_info

服务器无需支持客户端支持的最佳版本。如果服务器不支持与客户端相同的版本,可以提供 某个其他版本以期待客户端能够接受。

Certificate

典型的Certificate消息用于携带服务器X.509证书链。证书链是以ASN.1 DER编码的一系列证书,一个接着一个组合而成。主证书必须第一个发送,中间证书按照正确的顺序跟在主证书之后。根证书可以并且应该省略掉,因为在这个场景中它没有用处。

服务器必须保证它发送的证书与选择的算法套件一致。比方说,公钥算法与套件中使用的必须匹配。除此以外,一些密钥交换算法依赖嵌入证书的特定数据,而且要求证书必须以客户端支 持的算法签名。所有这些都表明服务器需要配置多个证书(每个证书可能会配备不同的证书链)。

Certificate消息是可选的,因为并非所有套件都使用身份验证,也并非所有身份验证方法都需要证书。更进一步说,虽然消息默认使用X.509证书,但是也可以携带其他形式的标志;一些 套件就依赖PGP密钥 。

ServerKeyExchange

ServerKeyExchange消息的目的是携带密钥交换的额外数据。消息内容对于不同的协商算法套件都会存在差异。在某些场景中,服务器不需要发送任何内容,这意味着在这些场景中根本不会 发送ServerKeyExchange消息。

ServerHelloDone

ServerHelloDone消息表明服务器已经将所有预计的握手消息发送完毕。在此之后,服务器会等待客户端发送消息。

ClientKeyExchange

ClientKeyExchange消息携带客户端为密钥交换提供的所有信息。这个消息受协商的密码套件 的影响,内容随着不同的协商密码套件而不同。

ChangeCipherSpec

ChangeCipherSpec消息表明发送端已取得用以生成连接参数的足够信息,已生成加密密钥, 并且将切换到加密模式。客户端和服务器在条件成熟时都会发送这个消息。

Finished

Finished消息意味着握手已经完成。消息内容将加密,以便双方可以安全地交换验证整个握 手完整性所需的数据。

密钥交换

密钥交换是握手过程中最引人入胜的部分。在TLS中,会话安全性取决于称为主密钥(master secret)的48字节共享密钥。密钥交换的目的是计算另一个值,即预主密钥(premaster secret)。 这个值是组成主密钥的来源。

RSA 密钥交换

RSA密钥交换的过程十分直截了当。客户端生成预主密钥(46字节随机数),使用服务器公钥对其加密,将其包含在ClientKeyExchange消息中,最后发送出去。服务器只需要使用私钥解密这条消息就能取出预主密钥。

密钥规格变更协议(change cipher spec protocol)

应用数据协议(application data protocol)

应用数据协议携带着应用消息,只以TLS的角度考虑的话,这些就是数据缓冲区。记录层使 用当前连接安全参数对这些消息进行打包、碎片整理和加密。

警报协议(alert protocol)

警报的目的是以简单的通知机制告知对端通信出现异常状况。它通常会携带close_notify异 常,在连接关闭时使用,报告错误。警报非常简单,只有两个字段:

struct { 
	AlertLevel level; 
	AlertDescription description; 
} Alert;

Reference