吐血整理,HTTPS看这篇就够了,一次给你说个明白

概要:吐血整理!HTTPS相关的知识点,看这篇就够了。
        本篇博客从安全的通信的四个特性开始,介绍完各种常见的加密方式(对称加密、非对称加密)后,为了方便理解HTTPS设计的原理尝试利用各种加密方式的组合一步步推导出一个完整安全的通信协议。后面对HTTPS的TLS握手、TLS协议的发展历史、HTTPS完整的通信过程进行了详细完整的说明。并且列举了各种HTTPS的优化方案,包括OSCP、会话复用等。在本篇博客的最后,进行了HTTPS配置的实战,帮助大家直上手HTTPS的完整配置过程。


关于HTTP协议的详情,可以参考博主上一篇博客: HTTP协议看这篇就够用了



一、什么是安全的通信?HTTP为啥不安全?

什么是安全的通信过程?
通常认为如果通信的过程具备了4个特性,就认为通信是安全的。这四个特性是:机密性完整性身份认证不可否认。一般来说只要满足前3个特性就可以解决大部分的通信问题,但是如果缺了 不可否认的特性,那么通信事务的真实性也得不到保证。

特性说明
机密性对数据保密,只有可信的人能看懂。
完整性/一致性保证数据从发送到接收能辨别数据是否被篡改,是否还是原状。
身份认证消息只发送给可信的人
不可否认不能否认自己发送信息的行为和信息的内容。

HTTP为啥不安全?

  1. HTTP明文传输数据 破坏了数据的机密性,
  2. HTTP传输数据没有保证发送和接收一致的机制,数据被拦截可以直接被篡改,对中间人攻击毫无还手之力。
  3. HTTP没有身份认证机制,同时也就满足不了 不可否认的特性。



二、什么是HTTPS

HTTPS全称是 HyperText Transfer Protocol over Secure Socket Layer,超文本传输安全协议,是互联网未来发展的趋势。HTTPS里用到了对称加密、非对称加密、摘要算法、数字签名、证书、认证中心等,来构建了符合四大特性的安全通信。

  1. HTTPS对传输的数据进行加密,建立了一个安全的传输通道保证传输过程中的数据安全。
  2. 对网站服务器进行了真实的身份校验。
  3. Https是身披SSL/TLS外壳的HTTP协议,它并非一个新的协议而是在HTTP的基础上新增了安全层(SSL/TLS),HTTPS先和安全层通信,然后安全层和TCP层通信。

image.png
image.png


三、增加SSL/TLS如何实现安全通信的

TLS全称传输安全层协议,Transport Layer Security Protocol,TLS/SSL是一种加密通道的规范。
SSL全称 Secure Sockets Layer 安全套接字协议

TLS/SSL的发展历史

版本描述
SSL 1.0存在严重的安全漏洞,从未公开过
SSL 2.0在1995年2月发布,但是存在数个严重的安全漏洞很快被3,0替代
SSL 3.01996年发布
TLS 1.0IETF对SSL3.0进行了标准化,并添加了少数机制 但是几乎和SSL3.0一样
TLS 1.1在RFC 4346中定义,2006年4月发布
TLS 1.2在RFC 5246中定义 2008年8月发布
TLS 1.3在RFC 8446中定义,于2018年8发表。

TLS协议是由TLS记录协议和TLS握手协议叠加而成的

记录协议:TLS Record protocol

  • TLS记录协议位于TLS握手协议的下层,是负责使用对称密码进行加密通信的部分
  • 加密使用的秘钥,是通过握手协议在服务端和客户端之间协商决定的

握手协议:TLS Handshaking Protocols

  • 由TLS Change Ciper Spec Protocol(密码规格变更协议) 和TLS ALert Protocol(警告协议)组成
  • 负责在客户端和服务器之间协商决定密码算法和共享秘钥
  • 密码规格变动协议负责向通信对象传达变更密码方式的信号,协议中途发生错误时,就会通过警告协议传达给对方。
  • 警告协议是TLS握手协议负责在发送错误时将错误传达给对方。

image.png

由于有了传输安全层TLS,所以HTTPS比HTTP的安全性大幅提高

  1. TLS Record Protocol 保证了数据的隐私性和完整性
  2. TLS Handshaking Protocols实现了身份认证。



四、对称加密和不对称加密算法

4.1 对称加密

image.png

  • 对称加密定义:采用单钥密码系统的加密方法,同一个秘钥可以同时用作信息的加密和解密。这种加密方法称为对称加密,也称为单秘钥加密。
  • 加密原理:对称加密通常是使用较小的秘钥,一般小于256bit。秘钥越大,加密与解密的过程就越慢,反之如果用1bit来做秘钥,那就不是1就是0。所以秘钥的大小要在安全性和效率上进行取舍,一般小于256bit。
  • 常见算法
    • DES (Data Encryption Stamdard) 数据标准加密标准。现在用的较少,安全性不够可以被暴力破解出来。
    • 3DES原理几乎和DES是一样的,只是要用三个密钥来加密增加加密强度。但是这样要维护3个密钥,太麻烦了。
    • AES(Advvance Encryption Standard) 高级加密标准,用来替换原来的DES算法,目前美国国家安全局、苹果公司,都有采用。是公认的最安全的加密算法,AES128 和AES256主要的区别就是秘钥长度不同和加密的轮次不同,AES128是10轮,AES256是14轮,AES256要更安全。
  • 特点 :
    • 优点: 算法公开,加密解密效率高。
    • 缺点: 相对来说不够安全,因为只有一把密钥。客户端和服务端都需要维护大量的秘钥,而各个端的安全措施没法保证,一旦泄露密码就失去了加密的意义。

4.2 非对称加密

非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。

非对称加密: 非对称加密需要两个秘钥,公钥(public key) 和私钥(private key),公钥和私钥都是成对存在。公钥可以公开出去,这样就不需要通信的双方都维护大量的秘钥了,这样安全性就得到了保证。但是加密解密的速度不如非对称加密。
常用算法: RSA、DSA、ECDSA
image.png


五、 推导如何结合加密设计安全的通信

要解决的问题:

  1. 通信被窃听(机密性)
  2. 报文被篡改(完整性)
  3. 通信身份被伪装 (不可否认、身份认证)

方案1:只利用对称加密传输

  1. 服务器告知客户端密钥
  2. 双方使用密钥加密通信数据

缺陷:

  1. 如果一个服务器只用一个密钥服务所有用户,服务器又无法区分来请求密钥的是不是真正的用户,那加密措施就形同虚设。黑客请求到密钥后可以照样解密和修改所有的数据。
  2. 如果服务器对每个用户分别生成一个密钥,一个是维护成本巨大,第二个仍然无法防住黑客,因为密钥如何交给客户还是个问题,如果黑客一开始就截获了密钥,那么双方传输的过程对黑客来说仍然是透明的

方案2:用非对称加密来传输

  1. 客户端通信前先请求服务器的公钥,私钥保存在服务器中。数据使用公钥加密,
  2. 客户端使用公钥加密数据发送给服务器。这样客户端发送的数据对黑客就不可见了。

缺陷:1. 每次都非对称加密解密效率过低。2. 如果截获了 服务器的公钥,那么服务器返回的数据对黑客仍然可见


方案3:非对称加密结合对称加密

  1. 客户端向服务器申请公钥
  2. 客户端本地生成一个密码,并且使用公钥加密密码内容发送给服务端
  3. 服务端收到密码后,服务端客户端之间后续的通信便使用密码和对称加密的方式来进行通信。
  4. 这样的话,因为密码的传输只有服务端能解密 黑客无法窃取加密的密码,也就无法监听通信的内容

解决问题: 解决了内容可能被窃听的问题

仍然存在的缺陷:
客户端无法辨别对方是不是真是的服务器,还是黑客的服务器。如果黑客进行中间人攻击,对客户端伪装成服务器,对真正的服务器伪装成客户端,那么还是能获取到内容并且进行篡改。针对这种情况,HTTPS引入了 数字签名机制和证书机制,来保证了身份无法被伪装,并解决了内容被篡改的问题。
image.png



六、数字签名机制


数字签名机制的作用

  1. 保证消息在传输过程中无法被篡改
  2. 保证消息是由发送方签名并发出的,因为非对称加密的特性只能由接收方解密

数字签名的过程

  1. 将要发送的数据,使用摘要算法,生成消息摘要
  2. 发送者利用私钥加密需要发送的数据,与原文一起发送给接收者。

image.png

校验签名的过程

  1. 接收方收到数据后,先使用公钥解密出数字签名
  2. 按照同样的摘要算法,得出收到数据的摘要,和收到的摘要进行比对
  3. 如果摘要不一致,那么就说明这条消息遭到了篡改,便抛弃这条消息。
  4. 常见的摘要算法分为三类
    1. MD(Message Digest) 消息摘要算法
    2. SHA(Secure Hash Algorithm) 安全散列算法
    3. MAC(Message Authentication Code) 消息认证码

image.png

总结:

  1. 如果客户端提前知道服务端的公钥,收到服务器发来的消息能解密并且能验证签名成功,那么就能确定消息来自服务器并且未被篡改。因为一旦中途被修改,私钥只有真正的服务器才有,便无法重新生成正确的摘要信息了。
  2. 如果公钥是从服务端请求到客户端的话,客户端便无法确定公钥是不是来自真正的服务端,所以还需要一个能验证公钥是属于服务器的一个机制。HTTPS引入了证书机制,并且引入了CA证书颁发机构来证明公钥来自服务器。



七、证书机制

数字证书

  1. 是一个经过证书认证机构认证并签名的,包含公钥、拥有者信息的一组数据文件。用于证明使用者的身份。
  2. 证书的类型很多,用在HTTPS上的SSL证书只是其中一种,常见的证书有如下这些
    1. SSL证书:用于HTTPS的加密传输,包含组织信息、域名信息、公钥、证书有效期等信息
    2. 代码签名证书:用于签名二进制文件,比如windows内核驱动,浏览器插件、java代码签名等
    3. 客户端证书:用于加密邮件
    4. 双因素证书,网银的USB KEY就是这种证书

CA-证书认证机构

CA是证书的签发机构,是公钥基础设施(Public Key Infrastructure PKI)的核心。CA负责签发证书,认证证书、管理已颁发证书的机构。

申请SSL证书的过程

  1. 证书的使用者,向CA提交 公钥、组织信息、域名信息 并申请CA机构的认证
  2. CA机构通过线上、线下等多重手段验证使用者提供的信息的真实性。
  3. CA机构审核通过便会向申请者签发认证文件,也就是证书。

SSL证书的内容

  1. 申请者的公钥、申请者的组织信息、签发机构的信息、有效时间、证书序列号等信息的明文
  2. CA机构的数字签名。CA机构会对明文信息进行摘要,然后使用CA机构的私钥对摘要数据进行加密,这个密文就是CA机构的签名。

证书机制如何保证请求的服务端是真实的服务端**

  1. 证书机制最大的杀器就是CA机构将自身的CA证书集成在了各大浏览器和操作系统之中,省略了从网络上请求公钥的这一过程,也就避免了申请公钥的过程被黑客劫持的问题。
  2. 客户端从服务端获取到了证书后,通过相同的散列函数计算明文的信息摘要。
  3. 客户端利用自身的CA机构公钥,对证书文件的CA签名进行解密,如果能成功解密,并且和第二步计算出来的摘要一致那么这个证书就是可信的。如果客户端中没有对应CA机构的证书(包含公钥)那么证书就会被判定为非法。所以我们要安装和使用正版的浏览器和操作系统。
  4. 客户端还会验证正式的域名、有效期等信息,如果不满足条件那么证书也被认为是无效的。

SSL证书的分类

  • DV 域名型SSL 一般用于个人站点
  • OV 企业型SSL 一般用于企业官网
  • EV 增强型SSL 一般用于对安全需求更强的企业官网、电商、互联网金融网站。

申请证书的方式

  1. 向Let’s Encrypt这种任何人都可申请的机构,申请免费的证书,有效期有90天,但是可以使用Certbot工具自动续订。
  2. 向阿里云这种云服务厂商申请购买证书。



八、完整的HTTPS的通信过程

HTTP协议的通信开始过程会经历DNS解析,然后TCP三次握手建立连接,然后就开始传输数据了。但是在HTTPS中,TCP连接建立后,还有一个SSL/TLS层握手的过程,用于在TCP连接之上建立安全连接。最后才开始收发HTTP报文。这个TLS握手的过程,就是HTTPS安全通信的核心!
image.png

8.1 TLS1.2 握手过程

image.png
TL握手的过程中传输的数据形式:明文->非对称加密->对称加密。TLS握手过程进行密钥交换的话,有两种密钥交换算法,一种称为ECDHE密钥交换算法,另一种是RSA密钥交换算法。现在基本上都是ECDHE密钥交换算法。

第一步 客户端发出明文请求 称为Client Hellow
包含这些信息:1.TLS协议版本号 2.一个随机数称为 Client random 3.客户端支持的加密方法 Cipher Suites(密码套件)

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)

第二步 服务端确认加密方法给出证书和随机数 Server Hellow

Handshake Protocol: Server Hello
    Version: TLS 1.2 (0x0303)
    Random: 0e6320f21bae50842e96…
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)

Handshake Protocol: Server Key Exchange
    EC Diffie-Hellman Server Params
        Curve Type: named_curve (0x03)
        Named Curve: x25519 (0x001d)
        Pubkey: 3b39deaf00217894e...
        Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
        Signature: 37141adac38ea4...
  1. 服务端收到Client Hellow后,会确认一下TLS的版本,然后给出本次通信的加密方法,并且给出一个随机数 Server Random
  2. 此次给出的信息中还包含证书的信息 Server Certificate
  3. 如果使用的是ECDHE的秘钥交换算法,还会包含Server Key Exchange信息,里面包含Server Param 其中是,ECDHE算法(椭圆曲线算法)随机生成的公钥信息,并且服务器用自己的私钥对它进行了签名。客户端验证完服务端的证书后,就可以根据证书的公钥来验证该信息是否来自服务器,并且是否被篡改。

第三步 客户端验证证书的有效性

  1. 证书路径信任链逐级校验通过(确认颁发证书的CA是否受信)
  2. 签名可以被CA公钥解密 (确认证书是否由其生命的CA颁发)
  3. 验证解密出的摘要和证书公开内容生成的摘要可以匹配 (确认证书未被篡改)
  4. 确定当前访问的资源属于证书的域名 (确认网站和证书匹配)

第四步 Client Key Exchange 客户端生成一个椭圆曲线的公钥

Handshake Protocol: Client Key Exchange
    EC Diffie-Hellman Client Params
        Pubkey: 8c674d0e08dc27b5eaa…

到这一步,服务端客户端都有了秘钥交换的两个参数,Client Params 、Server Params ,然后互相使用ECDHE算法得出一个新的参数“Pre _Master" 可以理解为也是一个随机数。Pre_Master计算的过程十分复杂,但是保证了黑客就算得到了之前的参数也算不出这个随机数。

第五步 使用伪随机算法利用 Pre_Master、Client Random、Server Random 算出Master Secret

# PRF 伪随机数算法
master_secret = PRF(pre_master_secret, "master secret",ClientHello.random + ServerHello.random)

  1. TLS的设计者,不信任客户端或者服务端的Random算法的可靠性,为了保证完全随机和不可预测,所以将三个不可靠的随机数混合起来得出Master Secret 主秘钥。
  2. 主秘钥有48字节,但是它也不是最终通信的会话秘钥,还会继续用PRF拓展出更多的秘钥来通信。例如客户端发送消息用的 Client_write_key、服务器发送用的会话秘钥 server_write_key 等等,避免了只使用一个秘钥带来的安全隐患。

第六步 客户端发送Change Cipher Spec 和Finished消息

  • 秘钥生成完毕后,握手就快结束了。客户端发送一个Change Chipher Spec (更改密码规则) 的消息和Finished消息。这俩消息通过一个TCP报文就发出去了。
  • Change Chipher Spec 相当于告诉服务端,后面开始使用对称加密算法通信了,使用的对称加密算法是当时Server Hellow时说好的。
  • Finished消息 会对之前发送的所有数据做一个摘要,然后用新的对称加密算法加密一下。相当于让服务器验证一下加密方式对不对。

第七步 服务端发送 Change Cipher Spec 和Finished消息
和第六步一样,服务端也发送 Change Cipher Spec 和Finished消息相当于双方都验证一下加密解密是否OK,握手结束后,双方就使用对称加密方式来发送被加密的Htpp请求和响应了。


8.2 ECDHE握手算法和RSA握手算法

ECDHE秘钥交换和RSA秘钥交换.jpg
在8.1中描述的是如今主流的TLS握手方式,与传统的握手有两点不同

  1. 使用了EDCHE实现了秘钥交换,而不是RSA,所以会有Server Key Exchange的 TLS消息
  2. 使用了EDCHE 所以客户端可以不等待服务器发回 “Finished” 确认消息来完成握手,就可以立即发出Http报文,省去了一个消息往返的时间。这个机制称为 **TLS False Start ,**意思是抢跑,和Tcp Fast Open 有点像,都是不等连接完全建立就提前发送应用数据提高效率。因为最后出错的可能性非常小。

8.3 TLS 1.3的变化


TLS 1.3 记录格式不变,向后兼容

  • TLS 1.3 为了让老设备能继续使用,所以保持了现有的记录格式不变。通过伪装实现兼容!1.3 在记录的末尾新增一系列的拓展字段 **扩展协议(Extension Protocol)**来新增新的功能,这样老版本TLS会直接忽略,新版本则可以使用新的拓展。这就实现了向后兼容!
  • 记录头的 Version 字段被兼容性“固定”的情况下,只要是 TLS1.3 协议,握手的“Hello”消息后面就必须有“supported_versions”扩展,它标记了 TLS 的版本号,使用它就能区分新旧协议。
Handshake Protocol: Client Hello
    Version: TLS 1.2 (0x0303)
    Extension: supported_versions (len=11)
        Supported Version: TLS 1.3 (0x0304)
        Supported Version: TLS 1.2 (0x0303)

TLS1.3 安全强化调整

  • 伪随机数函数由 PRF 升级为 HKDF(HMAC-based Extract-and-Expand Key Derivation Function);
  • 明确禁止在记录协议里使用压缩;
  • 废除了 RC4、DES 对称加密算法;
  • 废除了 ECB、CBC 等传统分组模式;
  • 废除了 MD5、SHA1、SHA-224 摘要算法;
  • 废除了 RSA、DH 密钥交换算法和许多命名曲线

算法精简的好处:“减肥瘦身”之后,TLS1.3 里只保留了 AES、ChaCha20 对称加密算法,分组模式只能用 AEAD 的 GCM、CCM 和 Poly1305,摘要算法只能用 SHA256、SHA384,密钥交换算法只有 ECDHE 和 DHE,椭圆曲线也被“砍”到只剩 P-256 和 x25519 等 5 种。
废除RSA密钥交换的好处: 之前浏览器默认使用ECDHE而不是RSA做秘钥交换,是因为它不具有**“前向安全”,**如果有黑客长期收集系统传输的报文,一旦某日获取或者破解了私钥,那么黑客就能解密之前所有的报文。这就是所谓的“今日截获,明日破解”。而ECDHE算法则是“一次一秘”就算某次被破解,其他历史消息仍是安全的。

TLS 1.3的性能提升

  • 在TLS1.2中完成TLS握手,需要两个RTT时间,延迟过大,现在因为TLS1.3密码套件组合大幅简化,没有必要继续走之前复杂的协商流程。TLS 1.3压缩了之前Hellow的协商过程, 删除了 Key Exchange消息 握手时间减少到了 1RTT
  • 具体做法:利用了拓展性,客户端在Client Hellow时,“supported_groups”直接带上支持的曲线,key_share”直接带上对应的客户端公钥,用“signature_algorithms”带上签名算法。服务器收到后在这些扩展里选定一个曲线和参数,再用“key_share”扩展返回服务器这边的公钥参数,就实现了双方的密钥交换,后面的流程就和 1.2 基本一样了。

TLS 1.3 握手分析
image.png



九、HTTPS的性能优化


9.0 HTTPS那些部分可以优化

HTTP的性能优化的点在哪儿呢? 从HTTP和HTTPS的对比来看,HTTPS主要就是多了连接时的非对称加密握手,和握手后的对称加密报文传输。我们主要能进行优化的地方,就是在非对称加密握手部分。

  • TLS协议封装和解析 HTTPS所有数据都是按照TLS record封装和解析
  • 消息一致性验证 每一段消息内容都需要进行完整性校验
  • 对称加密报文传输:目前流行的AES和ChaCha20这种对称加密算法性能都非常好,并且还有硬件优化。所以在对称加密报文传输对性能的损耗非常小,几乎没有可优化的地方。
  • 非对称加密握手 (主要)
    • 握手消息带来的最长 2RTT的时延(TLS1.3 1RTT)
    • 客户端和服务器都需要生成用于秘钥交换的公钥(ECDHE)
    • 验证证书时访问CA获取CRL(证书吊销列表)或OSCP(在线证书状态协议)
    • 非对称加密解密处理"Pre-Master"

HTTPS性能损耗的图示
image.png

9.1 硬件优化

首先明确:HTTPS连接是属于计算密集型的任务,而不是I/O密集型,所以如果升级硬件来提升性能,钱应该花在更快的CPU上,而不是网卡、带宽、ssd这种。

  • 升级更快的CPU 最好内建AES优化,这样既能加速握手也能加速传输。
  • 购买SSL加速卡 加密解密时调用它的API,让专门的硬件来做非对称的加密解密,分担CPU的压力。
  • 搭建SSL加速服务器 用专门的服务器集群,来专门负责TLS握手时的加密解密计算,性能比单纯的加速卡强大的多。

9.2 软件优化

9.2.1 升级软件

新版本的软件往往优化更好。例如linux内核由2.x升级到 4.x,nginx1.6升级到nginx1.16等等

9.2.2 使用效率更高的协议

  1. 升级到TLS 1.3 因为它大幅度优化了TLS握手的过程,完全握手只需要1RTT并且更加安全
  2. 如果只能是TLS1.2 那么握手的秘钥交换协议尽量采用ECDHE算法,它的运算速度更快安全性高,并且还支持 False Start 抢跑,能节省1个RTT的时间,达到TLS1.3类似的效果
  3. 调整算法优先级,使得尽可能使用的高性能椭圆曲线算法,性能最好的是 “x25519”其次是P256。对称加密算法可以选择 “AES_128GCM”性能就比“AES_256_GCM”略快。
ssl_ciphers   TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:EECDH+CHACHA20;
ssl_ecdh_curve              X25519:P-256;

9.2.3 优化证书校验的过程

HTTPS的证书机制决定了,HTTPS在建立连接过程中会使用服务端发回的证书,向CA机构来验证证书的真假,来保证访问的是真实的服务器,这一步也会带来很大的时延。优化这一步主要从证书的传输证书的验证下手。

优化证书的传输
服务器的证书可以选择椭圆曲线(ECDSA)证书而不是 RSA 证书,因为 224 位的 ECC 相当于 2048 位的 RSA,所以椭圆曲线证书的“个头”要比 RSA 小很多,即能够节约带宽也能减少客户端的运算量,可谓“一举两得”。
这里的ECDSA和RSA是对称加密算法的区别,选用ECDSA非对称加密算法的证书更小。
优化证书的校验 OCSP Stapling(OCSP证书装订)
客户端校验证书过程很复杂,除了要公钥解密验证证书链,客户端有时候还要去访问CA,下载CRL或者OCSP数据,来判断证书是否过期或者被吊销。

  1. 定期请求CRL(Certificate revocation list 证书吊销列表)判断证书是否被吊销:由于CRL会越来越大,所以实用性越来越低所以现在基本上不用了。取而代之的是OCSP
  2. OCSP(Online Certificate Status Protocol)在线证书状态协议 :向CA发送请求,验证编号对应的证书是否有效,OCSP至少也要有一次网络请求的消耗,并且速度还取决于CA服务器。所以为了优化这一步出现了 OCSP Stapling
  3. OCSP Stapling 的原理就是让服务器提前访问CA获取到OSCP的响应,然后在握手时随着证书一起发送给客户端。免去了客户端连接CA查询时的时间。

9.2.4 会话复用 (避免短时间重复的TLS握手)

HTTPS 建立连接的过程:先是 TCP 三次握手,然后是 TLS 一次握手。这后一次握手的重点是算出主密钥“Master Secret”,而主密钥每次连接都要重新计算,未免有点太浪费了,如果能够把“辛辛苦苦”算出来的主密钥缓存一下“重用”,不就可以免去了握手和计算的成本了吗?

Session ID 会话复用
原理:

  1. 客户端和服务器首次连接后各自保存一个会话的 ID 号,内存里存储主密钥和其他相关的信息。当
  2. 客户端再次连接时发一个 ID 过来,服务器就在内存里找,找到就直接用主密钥恢复会话状态,跳过证书验证和密钥交换,只用一个消息往返就可以建立安全通信。

缺陷: 服务端需要保留每个连接的会话数据,对于用户量大的网站来说就是大问题。加重服务器的负担。

Session Ticket 会话复用
原理:

  1. 服务器加密会话信息,用New Session Ticket 消息发送给客户端,由客户端保存。
  2. 重连的时候,客户端在拓展字段里带上 session_ticke字段,里面带上Ticket服务端解密后验证有效期,就可以回复会话,直接开始加密通信

缺陷: SessionTicket 方案,需要使用一个固定的秘钥文件,ticket_key 来加密Ticket,为了防止秘钥被破解,保证“前向安全” 秘钥文件需要定期轮换。

TLS 1.3的预共享秘钥
原理:
false start、session id、session ticket 等方式,只能实现1RTT的握手过程,但是TLS1.3进一步实现了0-RTT。原理和“Session Ticket”差不多,但在发送 Ticket 的同时会带上应用数据(Early Data),免去了 1.2 里的服务器确认步骤,这种方式叫“Pre-shared Key”,简称为“PSK”。
缺陷: 有重放攻击的风险,黑客截获了PSK数据后,反复向服务器发送。解决办法是消息里加入时间戳、nonce验证,或者"一次性票证"限制重复放。



十、工作中开始使用HTTPS

使用HTTPS的必要性

  1. 移动应用的一些开发平台在 2017 年就相继发出通知,要求所有的应用必须使用 HTTPS 连接,禁止不安全的 HTTP。
  2. 主流的浏览器将HTTP网站标注为不安全,给用户心理压力。
  3. 主流搜索引擎优先收录HTTPS站点。

使用HTTPS的步骤

第一步:申请证书

  1. 证书可以购买商业证书,也可以使用 let’s encrypt这种免费证书。而且阿里云一年也有二十个免费证书的额度。
  2. 证书应当同时申请RSA和ECDSA两种不同加密算法的证书,Nginx中可以配置双证书验证。这样如果客户端支持 ECDSA时就能选用更快的ECDSA证书,同时也兼容只支持RSA的客户端。

第二步:配置证书

在nginx上配置证书 只要在“listen”指令后面加上参数“ssl”,再配上申请的证书文件就可以实现最基本的 HTTPS。

listen                443 ssl;

ssl_certificate       xxx_rsa.crt;  #rsa2048 cert
ssl_certificate_key   xxx_rsa.key;  #rsa2048 private key

ssl_certificate       xxx_ecc.crt;  #ecdsa cert
ssl_certificate_key   xxx_ecc.key;  #ecdsa private ke

第三步:可选优化项

  1. 为了提高 HTTPS 的安全系数和性能,强制 Nginx 只支持 TLS1.2 以上的协议
  2. 打开“Session Ticket”会话复用
  3. 开启服务器ssl套件优先,避免客户端使用较弱的套件。
  4. 密码套件向TLS1.3看齐,只使用ECDHE、AES 和 ChaCha20 支持FALSE Start
#提高 HTTPS 的安全系数和性能,强制 Nginx 只支持 TLS1.2 以上的协议
ssl_protocols               TLSv1.2 TLSv1.3;
ssl_session_timeout         5m;
#打开“Session Ticket”会话复用
ssl_session_tickets         on;
ssl_session_ticket_key      ticket.key;

#开启服务器ssl套件优先,避免客户端使用较弱的套件
ssl_prefer_server_ciphers   on;
#指定支持的密码套件
ssl_ciphers   ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES128:!MD5:!SHA1;

#如果使用了OpenSSL 的分支 BorringSSL,可以配置等价密码组, 客户端硬件没有 AES 优化,服务器就会顺着客户端的意思,优先选择与 AES“等价”的 ChaCha20 算法,让客户端能够快一点
ssl_ciphers [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305];

第四步:测试HTTPS效果

可以访问 https://www.ssllabs.com/ 测试配置完成后的https网站的安全性

虚拟主机问题

HTTP协议是支持多个域名在一个IP地址上运行的,这就是虚拟主机机制。WEB服务器是通过请求头的HOST字段,来区分访问的虚拟主机。

问题:HTTPS里TLS握手之后,才会开始发送头信息,但是握手的时候就需要验证域名的证书,怎么解决?
答:

  1. 早些时候,因为这个原因只能用IP来区分HTTPS的域名,每个HTTPS域名必须使用独立的IP。
  2. 后面出来了个补充条款—**SNI(Server Name Indication)**也是通过TLS协议的拓展字段实现的,客户端再Client Hellow时在拓展字段里带上域名信息,这样服务器就可以根据域名来选择证书了。就也支持虚拟主机了。
  3. Nginx 很早就基于 SNI 特性支持了 HTTPS 的虚拟主机。
Extension: server_name (len=19)
    Server Name Indication extension
        Server Name Type: host_name (0)
        Server Name: www.chrono.com

第五步:配置HTTP站点跳转HTTPS

很多旧的书签,或者是直接输入域名时会直接使用http协议访问,这时候就需要帮助用户重定向到HTTPS协议了。这在 Nginx 里也很容易做到,使用“return”或“rewrite”都可以。
nginx配置重定向示例

return 301 https://$host$request_uri;             #永久重定向
rewrite ^  https://$host$request_uri permanent;   #永久重定向

但是直接重定向会存在一些问题

  1. 多出了一次重定向请求,增大了延迟
  2. 会给黑客的中间人攻击的机会,劫持会话,篡改响应值跳转到恶意网站等。

HSTS(HTTP严格传输安全) 机制可以解决这个问题,原理是HTTPS发出的响应请求头里返回 **Strict-Transport-Security **字段,值是一个过期时间,告诉浏览器,以后访问我这个网站,直接使用https协议就好,不允许你先访问HTTP。这样不但节省了一次重定向,也让中间人攻击失去了机会。

add_header Strict-Transport-Security max-age=15768000; #182.5days
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值