让 nginx 支持ecc 和 rsa 双证书

RSA 和 ECC 证书的区别

首先,内置 ECDSA 公钥的证书称为 ECC 证书,内置 RSA 公钥的证书称为 RSA 证书
安全性方面,256 位 ECC Key 等同于 3072 位 RSA Key
运算速度上,ECC 运算速度 更快
且由于同等安全条件下,ECC 算法所需的 Key 更短,所以 ECC 证书拥有比 RSA 证书 更小的文件体积
那么综上,ECDHE 密钥交换 + ECDSA 数字签名无疑是坠吼滴选择。

我们看下 ecc 证书的 key 文件

[root@iz28wru16cpz ssl]# cat awen.me.ecc.key
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
SHcCAQEEEBQHlIr/d/F+AgOGd1+w3NY6MRtYFiF9Fv+UzRlX3va6oAoGCCqGSM49
AwEHoUQDQgAEjoo72OmWd6PWODdb1eeDg6bBKAq8NKfXqYlXLjk+V9RfegADMzHj
h8YyPxaDPa4XLE1HlcIw+20jWGYJgnr8Bw==
-----END EC PRIVATE KEY-----

然后看下 rsa 证书的 key

[root@iz28wru16cpz ssl]# cat awen.me.rsa.key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArqheINIhiqQVZzV2Sf8rV6NkteBJlNTCOJDSylzdL0igtNjf
ZAt6qep+de7+8YtZ87D1AVDU5d0OuPyV5EtfJ895km1WND0uq2D07ukc4SI2T0Hk
GHMnq16wmNkPZfJXEDgZDQNPnw0ex0eRfVLrnOtBM0uS6zVpM4iSZWzRBA/WTr3O
6b0wHkd41AVBY4bJ00vhn0RKX3U6I0QkhGRLI6i4po+dFZISWCZgEOt9XHhWlv53
fTNXatT/amN6pYj53ie34pLG8SgsYpPFThy5GOYWVaIQCd9QGsCwcXP+KBRd7B+b
ZQGxDyFg/CDA7L/5rKBE1fFnTrJ6yjMrCaEYPwIDAQABAoIBADFvqqTzlVbetsgt
07uCJDx8DSeFwo4D4q2MIH3y5xBZKFPIBwMUVLX/j6fl6/eGkAFwFwk2Tex6M46c
v/iMdPSZvzl5BStoHeuYV/u/s9Ltkh3A8sUQ4yuYc7fvyHH8tDP9DOooA8NrPUj+
sumcLOCPnjbcr0swJQTXJUjcEhVpxm6XGae4HffkYWiYu1vZlkdu1sft/xVONIC1
9lFDMdK6u6C8BQIjft0SpoAh6mC3WgFnaWkE4ZPLjiLY9EatsyqRIcx4+zRrWD9r
IZI4dNlYdYMNqgyenzmJuZTIOvBFpH3kF/4rctnKVflCG+utym/4U/tDLfen4AaB
cfceFDECgYEA19GTPi+W+q2SuKbnsu5586FuSuzPgf28r0NI9OipmMhkREPGNAfm
eexMmyfTqAe19S3WSbGnP/IhCsF30cUCS+joO7JYQzbQ2gnwAmEGIPUvoH+Y1QSt
eUj3FAwvPShqw0hw6qNejlVm8LHQsgt3gcNQoW4E7yYabf/vF21xWvMCgYEAzyz2
yEbc2XIb4MJ2g+7lVnh0Jkt+TZioJmwFzFaDNBw4B3q4xT0jHzCD2liDTgyrRRkK
4gYyDHoYUG2JG7rvCpVipNKYTrbpNjXQ0gFY2Yd4+xnO3dzcOQWb+Ixv5fMYk9QP
GkWM7ifsShiTDqmBWkVnwycgwaYSFCeCeeRVyIUCgYEAoMtoZOCYIFTKCAFyh4He
IoKX5gLh5/vgZMRAyxe9pDNJYQMN3R41vYks2jymGX8FNktV6LoP3jjMHXNfjk62
E1CIFlIeKJXirVDSHTOkmVGUFoR6ndtKVB7k127skyhVwwFp/6eQf4NpmtMgpkac
13Vp0Zxi2LsO3f3daRsFZbkCgYAXyO28KIaKYFNbBnhcxTyHJOUQ0HH8JC6J2rT/
tJ7ziJnWIfy8iDxUBFne43KPr1yqXimlsVhlnk7UTP8Es/1llajxi0v5HX7AvoTu
10DAGJGHInthdU3DLiWt71GZcMNNlXb2aS242dSC3Tdk44j6OCWlfgSAtvQ0ZCTS
oahHkQKBgDxlxKoaxwSlBTynwIgl4uGEex4rIc/IPzFHB3j52/z8wwef8A1UenLy
gbrW+SXQdzT+gh/1NUsInaAC/pX3x2JI2c02ncjoWO0nu8CD7T96ECf0C4XrNkuP
tr+pCEq5XjQeOwFgcyH7B8BUu2fANR19O53TnXa8kBXqGsJmYZNf
-----END RSA PRIVATE KEY-----

既然 ecc 证书比 rsa 证书这么好,那为啥不直接上 ecc,其实,ecc 也并不是完美的,并不是所有浏览器都支持 ECDHE 密钥交换,也就是说 ECC 证书的兼容性要差一些。例如在 Windows XP 中,使用 ECC 证书的网站时需要浏览器自行 TLS(例如 Firefox 的 TLS 自己实现,不依赖操作系统);Android 平台中,也需要 Android 4+ 才支持 ECC 证书。

那么在 Nginx 1.11.0 以后的版本开始提供 RSA/ECC 双证书的支持
它的实现原理是:分析在 TLS 握手中双方协商得到的 Cipher Suite,若支持 ECDSA 就返回 ECC 证书,反之返回 RSA 证书。

配置

 ssl on;
 #ecc 证书配置
 ssl_certificate /usr/local/nginx/ssl/awen.me.ecc.cer;
 ssl_certificate_key /usr/local/nginx/ssl/awen.me.ecc.key;
   # rsa 证书配置
 ssl_certificate /usr/local/nginx/ssl/awen.me.rsa.cer;
 ssl_certificate_key /usr/local/nginx/ssl/awen.me.rsa.key;

 # 支持的算法
 ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES:!MD5;

#优先采取服务器算法
 ssl_prefer_server_ciphers  on;
 # 支持的协议
 ssl_protocols              TLSv1.2 TLSv1.3;

测试

通过 test.sh 测试后各个平台对于密钥的支持情况如下:

通过 https://www.ssllabs.com/ssltest/analyze.html?d=awen.me 测试