False start

False Start 相当于客户端提前发送加密后的应用数据,不需要修改 TLS 协议, 目前大部分浏览器默认都会启用。
image.png
简而言之就是告诉Nginx在TLS握手时启用服务器算法优先,由服务器选择适配 算法而不是客户端。

会话恢复(Session Resumption)机制

SSL/TLS中的session跟HTTP的session类似,都是用来保存客户端和服务端之 间交互的一些记录,这里的SSL的session保存的是SSL的握手记录。 TLS有几个特征可以用来消除额外的来回,比如重用一个会话session,两个标 准会话重用机制是 session ID (RFC 5246) 和 session tickets (RFC 5077),使用 其中一个技术,一个客户端可以重用之前创建的会话,这个会话是之前和服务器进行握手成功的,这样可以减少一次来回过程

Session Cache:

一次TLS握手的结果是建立一条对称加密的数据通道,这条数据通道相关的参 数都可以在内存中保存的,所以服务端就可以针对这一套参数值生成一个ID, 叫做Session ID,使用该ID就可以直接复原对称加密的通信通道。所以当客户端 下一次请求(Client Hello)到达的时候,客户端如果携带了Session ID,服务 端就可以根据这个Session ID找到对应的Secure context,从而复原信道了。

OpenSSL的Session Cache是不能够跨进程共享的,而Nginx是一个多进程的 业务模型,如果每一个进程一份独立的Session Cache,就会导致同样一个SSL 连接,上一次被一个Worker进程服务,下一次是被另外一个Worker进程服务 的。使得整个OpenSSL在内存上造成极大的浪费,并且使得Cache的准确性大 幅度下滑。

所以Nginx就另外又实现了一套自己的Session Cache系统,这套系统是跨进 程的,使用的是共享内存,用红黑树的方式组织的Session Cache,并且对 Session ID的定义也重新进行了封装,最终形成了一个跨进程了Session Cache。
Session ID共享复用Nginx可以通过ssl_session_cache设置:
image.png
目前使用较多的配置是built-in和shared同时使用:
ssl_session_cache builtin:1000 shared:SSL:10m;
但是Nginx官方说只使用shared,性能会更高,配置方法为:
ssl_session_cache shared:SSL:10m;
Session Identifier 机制的弊端:

  • 负载均衡中,多机之间往往没有同步 session 信息,如果客户端两次请求没有落在同一台机器上就无法找到匹配的信息;
  • 服务端存储 Session ID 对应的信息不好控制失效时间,太短起不到作用, 太长又占用服务端大量资源。

ssl_session_timeout 5m;

Session Ticket

Session Ticket可以解决这些问题,Session Ticket 是用只有服务端知道的安全 密钥加密过的会话信息,最终保存在浏览器端。浏览器如果在 ClientHello 时带 上了 Session Ticket,只要服务器能成功解密就可以完成快速握手。 由于Session Ticket的客户端存储的特性,使得服务器完全就不需要管Session Cache方案需要面对的资源管理问题,唯一的代价就是一个解密计算的开销。同 时,天然的支持了分布式,但是前提是分布式的所有节点都需要使用同样的服 务器私有密钥(Session Ticket Encryption Key (STEK)),这无疑严重增加了危 险系数。所以很多公司在实现的时候都会隔一段时间统一更换STEK。

  1. # 开启Session Ticket 此处没有指定加密算法, openssl默认会生成随机数 key
  2. # 如果需要手动指定, 配置:ssl_session_ticket_key encode_decode.key;
  3. # key文件可以由openssl命令生成, 例如:openssl rand 80> ticket.key
  4. # 如果存在Nginx集群, 多个集群应用使用同一份key文件, 为保证安全性须每 隔一定频率更换key
  5. ssl_session_tickets on;

在TLS1.3中,Session Cache和Session Ticket都被完全的取消,取而代之的是 PSK(Pre Shared Key)。这个PSK并不是说每个客户端都要和服务端提前共享 一个密钥,而是与握手相同的首先使用非对称加密方法直接提前协商一个密钥 出来(psk_dhe_ke ),或者直接从之前协商出来的密钥参数中得出一个密钥 (psk_ke)。

HSTS

301需要一个RTT时间

原理
第一次通过HTTPS请求,服务器响应Strict-Transport-Security 头,以后尝试 访问这个网站的请求都会自动把HTTP替换为HTTPS。
当HSTS头设置的过期时间到了,后面通过HTTP的访问恢复到正常模式,不会再自动跳转到HTTPS。
每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期 时间,所以网站可以刷新这些信息,防止过期发生。
Chrome、Firefox等浏览器里,当您尝试访问该域名下的内容时,会产生一 个307 Internal Redirect(内部跳转),自动跳转到HTTPS请求。
image.png

OCSP

PKI:公钥基础设施(Public-Key Infrastructure):
公钥基础设施是用来实现基于公钥密码体制的密钥和证书的产生、管理、存 储、分发和撤销等功能。
那浏览器或者客户端如何知道当前使用的证书已经被吊销 了呢
OCSP(Online Certificate Status Protocol,在线证书状态协议)

OCSP Stapling 就是为了解决 OCSP 性能问题而生的,工作原理:
网站服务器将自行查询OCSP服务器并缓存响应结果,然后在与 浏览器进行TLS连接时将 OCSP 查询结果通过 Certificate Status 消息发送给浏 览器,这样浏览器就不需要再去查询了。
浏览器客户端也不再需要向任何第三方披露用户的浏览习惯,完美解决了隐私问题。

当客户端向服务器发起 SSL 握手请求时,服务器将证书的 OCSP 信息随证书 链一同发送给客户端,避免了客户端验证会产生的阻塞问题。

由于 OCSP 响应是无法伪造的,因此这一过程也不会产生额外的安全问题。

这个应该是 本来找CA验证的时候 也是用了RSA的 client本来就有CA的 公钥 ,服务器替 client去查了 证书的吊销状态 的结果 也是用了CA的私钥加密的 只要 自己本地浏览器存的公钥能 解析 就能证明结果没问题 而服务器端没有CA私钥 所以 伪造不了

image.png

其他方面

  1. # Nginx 里可以用“ssl_ciphers”“ssl_ecdh_curve”等指令配置服务器使用的密码套件和椭圆曲线,把优先使用的放在前面,例如:
  2. ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:EECDH+CHACHA20
  3. ssl_ecdh_curve X25519:P-256;
  4. # 为了提高 HTTPS 的安全系数和性能,你还可以强制 Nginx 只支持 TLS1.2 以上的协议,打开“Session Ticket”会话复用:
  5. ssl_protocols TLSv1.2 TLSv1.3;
  6. ssl_session_timeout 5m;
  7. ssl_session_tickets on;
  8. ssl_session_ticket_key ticket.key;
  9. # 密码套件的选择方面建议是以服务器的套件优先。
  10. # 这样可以避免恶意客户端故意选择较弱的套件、降低安全等级,
  11. # 然后密码套件向 TLS1.3“看齐”,只使用 ECDHEAES ChaCha20,支持“False Start”。
  12. ssl_prefer_server_ciphers on;
  13. 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;
  14. # TLS1.3pre-shared-key,实现0-RTTOCSP Stapling
  15. ssl_early_data on;
  16. ssl_stapling on;