背景
服务器是Windows server 2012 R2, 之前扫出安全问题,并提供解决方案
TLS/SSL Server Is Using Commonly Used Prime Numbers
The server is using a common or default prime number as a parameter during the Diffie-Hellman key exchange. This makes the secure session vulnerable to a precomputation attack. An attacker can spend a significant amount of time to generate a lookup/rainbow table for a particular prime number. This lookup table can then be used to obtain the shared secret for the handshake and decrypt the session.
Generate random Diffie-Hellman parameters
Configure the server to use a randomly generated Diffie-Hellman group. It's recommend that you generate a 2048-bit group. The simplest way of generating a new group is to use OpenSSL:
openssl dhparam -out dhparams.pem 2048
To use the DH parameters in newer versions of Apache (2.4.8 and newer) and OpenSSL 1.0.2 or later, you can directly specify your DH params file as follows:
SSLOpenSSLConfCmd DHParameters "{path to dhparams.pem}"
If you are using Apache with LibreSSL, or Apache 2.4.7 and OpenSSL 0.9.8a or later, you can append the DHparams you generated earlier to the end of your certificate file and reload the configuration.
For other products see the remediation steps suggested by the original researchers. (https://weakdh.org/sysadmin.html)
简单来说就是Client和Server进行key交换的时候用的DH算法并不安全。
那么怎么办呢,就是给Server端指定一些安全的Cipher Suites,我们的app部署在Tomcat上,自然按照指导(https://weakdh.org/sysadmin.html)配置Tomcat:
<Connector
ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_SHA,TLS_ECDHE_RSA_WITH_AES_256_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_SHA384,TLS_ECDHE_RSA_WITH_AES_256_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_128_SHA,TLS_DHE_DSS_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_256_SHA256,TLS_DHE_DSS_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_256_SHA"
/>
问题
我们把这些Cipher Suites格式话看一下:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
==================================
TLS_ECDHE_RSA_WITH_AES_128_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_SHA,
TLS_ECDHE_RSA_WITH_AES_256_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_SHA,
TLS_ECDHE_ECDSA_WITH_AES_256_SHA,
TLS_DHE_RSA_WITH_AES_128_SHA256,
TLS_DHE_RSA_WITH_AES_128_SHA,
TLS_DHE_DSS_WITH_AES_128_SHA256,
TLS_DHE_RSA_WITH_AES_256_SHA256,
TLS_DHE_DSS_WITH_AES_256_SHA,
TLS_DHE_RSA_WITH_AES_256_SHA
前6个还好说,后面这个suite是个啥,JDK8,甚至JDK7都没有这些,Windows本身也没有这些名称的suite。
JDK8:https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SupportedCipherSuites
JDK7: https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SupportedCipherSuites
Windows:
https://docs.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel
https://docs.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-8-1
后来我绞尽脑汁,各种检索,终于猜出这些suites可能是为了兼容更早(老旧)的应用(浏览器,JDK,OPENSSL等)所为,可以参考:https://ssl-config.mozilla.org/#server=tomcat&version=9.0.30&config=old&guideline=5.6
所以现在2021年底了,TLS1.3部分应用,TLS1.2普遍应用,SSL3彻底淘汰,这个“权威”文章不用更新的吗?或者做一些说明?
这个疑惑解决之后,我们再看前几个Cipher Suites, 通过网络抓包,我们发现在握手阶段,Client Hello的时候,客户端会带着一些Suites去和Server协商,但是有2两个Suites明明带着,服务端也支持,却无法建立连接。
我们以0xC02B
这个Suite举例,我们在Tomcat里配置,只支持该Suite,客户端请求中也带着该Suite,但是无法建立连接。
而,当我们在Tomat中配置,只支持0xC02B
这个suite(图片中的第一个)的时候,就可以正确建立连接了。
为什么?
知识不够就经过一番搜索+学习+串联+想象
首先,明白这些cipher suite的命名规范,具体可以看这里:https://wiki.mozilla.org/Security/Cipher_Suites
我们可以看到suite名称由多部分组成,协商确定某个suite之后,每一部分的算法都用于不同阶段
我们以cnblogs为例,抓包如下:
因为cnblogs的公钥是RSA公钥,所以验证的时候也要RSA算法。
我们再看一个不同的,以天猫为例
天猫的公钥不是RSA,而是ECC,还有个key param,所以验证的时候使用的算法必然是ECDSA
而我们环境Server使用的证书是自签名证书,公钥是RSA公钥,所以使用TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
不能协商成功。
参考:https://github.com/envoyproxy/envoy/issues/8983
最后
所以,不要完全盲目的遵循 https://weakdh.org/sysadmin.html 的陈年文章作为指导。