背景
服務器是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 的陳年文章作為指導。