HTTPS证书交换如何工作(如在suche.org上)?

对于那些不知道Suche.org是什么的人来说,它是一个网站,在每个类别的SSL实验室都有一个完美的A +评分:( Suche.org SSL实验室结果 )。 当我打开另一张关于不在Chrome中工作的ECC证书的票据时,我开始意识到这个网站,其中一名响应者以该网站为例。

我感到困惑的是,虽然报告的Protocol Support部分说,该网站使用TLSv1.2 …

 TLS 1.2 Yes TLS 1.1 No TLS 1.0 No SSL 3 No SSL 2 No 

这显然不是这样,因为在Handshake Simulation部分,它显示,一些模拟的老客户端正在使用TLSv1.0来连接…

 Android 4.0.4 EC 384 (SHA256) TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ECDH secp521r1 FS Android 4.1.1 EC 384 (SHA256) TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ECDH secp521r1 FS Android 4.2.2 EC 384 (SHA256) TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ECDH secp521r1 FS Android 4.3 EC 384 (SHA256) TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ECDH secp521r1 FS Android 4.4.2 EC 384 (SHA256) TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ECDH secp521r1 FS 

这有点令人沮丧,因为如果我禁用我的testing网站TLSv1.0像这样…

 # Apache example SSLProtocol all -SSLv3 -SSLv2 -TLSv1 

在我的testing网站上运行SSL实验室扫描得到一些较旧的客户端的以下内容:

 Android 4.0.4 Server closed connection Android 4.1.1 Server closed connection Android 4.2.2 Server closed connection Android 4.3 Server closed connection Android 4.4.2 EC 384 (SHA256) TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ECDH secp256r1 FS 

如何才能同时只允许TLSv1.2连接,同时还支持较老的客户端呢?

我很确定他们正在检查客户端的function并采取相应的行动,正如@Jeff的回答中所说的那样 。

为了得到一个想法如何可能看起来像细节,看看这个 。 它显示了使用HAProxy实现的实现,以根据其function为不同的客户提供不同的证书。 我已经做了一个完整的复制/粘贴,以防止链接腐烂,因为我认为这个问题可能在未来的利益:

SHA-1证书正在出来,你应该尽快升级到SHA-256证书…除非你有很老的客户端,并且必须保持一段时间的SHA-1兼容性。

如果您处于这种情况,您需要强制客户升级(困难)或实施某种forms的证书select逻辑:我们称之为“证书切换”。

最确定的select方法是向客户端提供SHA-256证书,客户端在signature_algorithms扩展中显式声明他们支持SHA256-RSA(0x0401)的TLS1.2 CLIENT HELLO。

签名算法扩展

现代的网页浏览器会发送这个扩展名。 但是,我不知道任何开源的负载平衡器,目前能够检查的signature_algorithms扩展的内容。 它可能会在未来,但现在实现证书交换的最简单的方法是使用HAProxy SNI ACL:如果客户端提供SNI扩展,请将其引导到提供SHA-256证书的后端。 如果它没有提供扩展名,那么假设它是一个说SSLv3的旧客户端,或者是一些TLS的破解版本,并且提供一个SHA-1证书。

这可以通过链接前端和后端在HAProxy中实现:

HAProxy证书交换

 global ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128 -SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-R SA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK frontend https-in bind 0.0.0.0:443 mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } use_backend jve_https if { req.ssl_sni -i jve.linuxwall.info } # fallback to backward compatible sha1 default_backend jve_https_sha1 backend jve_https mode tcp server jve_https 127.0.0.1:1665 frontend jve_https bind 127.0.0.1:1665 ssl no-sslv3 no-tlsv10 crt /etc/haproxy/certs/jve_sha256.pem tfo mode http option forwardfor use_backend jve backend jve_https_sha1 mode tcp server jve_https 127.0.0.1:1667 frontend jve_https_sha1 bind 127.0.0.1:1667 ssl crt /etc/haproxy/certs/jve_sha1.pem tfo ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA mode http option forwardfor use_backend jve backend jve rspadd Strict-Transport-Security:\ max-age=15768000 server jve 172.16.0.6:80 maxconn 128 

上面的configuration接收名为“https-in”的前端的入站stream量。 该前端处于TCP模式,并检查来自客户端的CLIENT HELLO的SNI扩展的值。 如果该值存在并与我们的目标站点相匹配,则将连接发送到名为“jve_https”的后端,后者将redirect到名为“jve_https”的前端,在该前端中将SHA256证书configuration并提供给客户端。

如果客户端无法提供带有SNI的客户端,或者呈现与我们的目标站点不匹配的SNI,它将被redirect到“https_jve_sha1”后端,然后到其对应的提供SHA1证书的前端。 该前端还支持较老的密码套件以适应较老的客户。

两个前端最终都会redirect到一个名为“jve”的后端,后者将stream量发送到目标Web服务器。

这是一个非常简单的configuration,最终可以使用更好的ACL(HAproxy定期添加新的ACL)进行改进,但对于基本的证书交换configuration,它可以完成工作!

https://community.qualys.com/thread/16387上也有类似的问题

我认为这个答案是解决scheme:

suche.org是一个聪明的实现。 据我了解,它查询客户的能力,然后只提供最好的可用,带走任何疑问。