在 CentOS 8 上指定 TLS 1.3 的加密算法


一、前言

最近把云主机升级到了 CentOS 8。

得益于系统内建的 OpenSSL 1.1.1 加密库,我终于可以愉快地使用 TLS 1.3 和 chacha20 加密算法咯~

但由于我的云主机并不支持 AES-NI,所以需要设置 chacha20 加密算法优先使用。

而在指定 TLS 1.3 加密算法时却遇到了麻烦……


二、发现问题

首先要知道,名称以 TLS_ 开头的几个加密算法是 TLS 1.3 专用的。

为了测试 CentOS 8 下的 Nginx 可以正常使用 chacha20 加密算法,我将 ssl_ciphers(也就是 Cipher List)设置成了:

TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

但后续在抓包检查 Server Hello 时发现了问题:使用 TLS 1.2 时服务器可以选择 chacha20 加密算法进行加密,但使用 TLS 1.3 时服务器依然选择了 AES 加密算法进行加密。

这就奇怪了,明明服务器没开启 AES 加密算法,但为什么还是用了 AES 加密算法进行加密??

后来通过 openssl ciphers 检查 Cipher List 时发现了端倪:无论 Cipher List 怎么设置,几个 TLS 1.3 专用的加密算法丝毫不受任何影响,哪怕是胡乱指定。

[[email protected] ~]# openssl ciphers TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305                                                        
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
[[email protected] ~]# openssl ciphers no_cipher                                                        
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256

这就尴尬了,看起来很像是 Bug,但我觉得 CentOS 预装的软件不太可能会出现这么低级的 Bug……


三、解决方法

在网上找了一圈之后,才发现原来 TLS 1.3 的 Cipher List 是需要单独设置的。也就是说,无论现在的 Cipher List 怎么设置,对 TLS 1.3 那几个加密算法来说都是无效的!

参考资料: #1529 (Could not configure TLS1.3 ciphers in OpenSSL 1.1.1 pre4) – nginx

如果需要指定 TLS 1.3 加密算法,需要修改 OpenSSL 配置文件下的 TLS 1.3 Cipher List。

这个配置文件是 /etc/crypto-policies/back-ends/opensslcnf.config,里面 Ciphersuites 一行就是用来设置全局 TLS 1.3 专用的 Cipher List。

附上 /etc/crypto-policies/back-ends/opensslcnf.config 的内容:

CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
MinProtocol = TLSv1.2

我将 Ciphersuites 修改为 TLS_CHACHA20_POLY1305_SHA256 保存之后,再执行 openssl ciphers 检查的时候就能达到预期效果了。

[[email protected] /]# openssl ciphers TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

openssl ciphers 命令也可使用 -ciphersuites 选项来指定 TLS 1.3 专用的 Cipher List。

当然了,现在配置 Cipher List 的时候可以把 TLS 1.3 相关的加密算法去掉,因为即使加上了也是没有任何作用的。

最后重新配置 Nginx,抓包,达到预期效果,解决!

事后我就很纳闷了,为啥 OpenSSL 要这样设计……

搜了一圈之后发现还真有人以为这个 Feature 是 Bug。

参考资料:Included TLS 1.3 ciphers in “openssl ciphers -V ” · Issue #5736 · openssl/openssl

好像有人说 OpenSSL 之所以这样设计是因为 TLS 1.3 的加密算法也就那 4 个,没有必要指定 Cipher List。我只想说您一定没体会过不支持 AES-NI 的痛吧。

发表评论

电子邮件地址不会被公开。