在IPSec中定期执行密钥更新是强制性的,比如华为防火墙上是每个小时或者每超过80GB流量就会更新一次SA。
但是TLS中并没有对密钥更新进行硬性规定,可能因为TLS通常用于短连接,对之方面要求低。TLS1.2及以前可以通过重协商(重新握手)来更换密钥,但这可能造成连接中断。TLS1.3中提供了专门的key update所握手消息进行密钥更新,但并没有规定密钥更新周期。
在RFC8446的5.5节提到对于一组密钥,AES-GCM可以对2400万个TLS记录进行安全的加密,一个TLS记录是16KB,也就是384GB的数据大小。看来日常环境中TLS并没有更新密钥的必要性,在nginx,firefox,chrome中我也没有发现有密钥更新的说明或相关配置。
在OpenVPN上可以使用–reneg-bytes和reneg-sec配置更新密钥的数据量和时间周期。不过OpenVPN并没有使用TLS的密钥更新机掉,OpenVPN自己实现了密钥管理,密钥交换,密钥重协商等,需要注意的是,它并不使用SSL握手最终确定的那些密钥,OpenVPN使用SSL握手仅仅是完成了连接者身份认证以及为后续的密钥管理,密钥交换,密钥交换以及控制信道构建一个安全的加密通道,完全类似于IKE的第一阶段协商。
另外在这个IETF提案中提到TLS1.3中自带的key update机制不是PFS(前向保密),所以重新定义了一个用于密钥更新的扩展,用于提供PFS的密钥更新。
在OpenSSL中可以调用SSL_key_update()函数执行TLS1.3的key update握手。
在QuicTLS(RFC9001)中对密钥更新做了更明确也更严格的要求,AES-123-GCM限制为2^23个数据包,1个数据包是1.5KB的话就是12GB的数据量。而且超过数据量后必须更新密钥或中断连接。Quic专门定义了一个key_updated事件,在密钥更新时会触发。QuicTLS并没有使用TLS1.3中的key update报文来更新密钥,而是使用Key Phase bit来进行密钥更新,而且QuicTLS要求两端同时进行密钥更新。在OpenSSL的ssl/quic/quic_record_util.c文件中定义了每种加密套件的AEAD用量限制,共定义了3种加客套件,分别由suite_aes128gcm,suite_aes256gcm,suite_chacha20poly1305这3个结构体表示。
参考:
https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/
https://datatracker.ietf.org/doc/html/rfc8446
https://datatracker.ietf.org/doc/draft-ietf-tls-extended-key-update/
http://shanks.link/blog/2022/07/01/openvpn%E5%8D%8F%E8%AE%AE%E8%A7%A3%E6%9E%90%E4%B9%8B%E7%BD%91%E7%BB%9C%E7%BB%93%E6%9E%84%E4%B9%8B%E5%A4%96/
https://docs.openssl.org/master/man3/SSL_key_update/
https://caddyserver.com/docs/json/apps/http/servers/tls_connection_policies/client_authentication/ca/http/tls/renegotiation/
https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/
https://autumnquiche.github.io/RFC9001_Chinese_Simplified/#6.6_Limits_on_AEAD_Usage
https://dev.to/shouhua_57/http3zhi-key-update-nod