Chromium 浏览器 TLS1.2 在 Server 2012 R2 上因 ADCS 颁发证书而失败

Chromium 浏览器 TLS1.2 在 Server 2012 R2 上因 ADCS 颁发证书而失败

tl;dr:使用 AD CS 颁发的证书时,Server 2012 R2 和基于 Chromium 的浏览器之间的 TLS 1.2 会失败。在 Server 2016+ 上以及在 2012 R2 上使用 Firefox/IE/Cygwin-curl 时运行良好。

我们有几个内部 Server 2012 R2 Web 服务器,我们正尝试将其从公开颁发的证书转移到由我们的 AD 集成 CA 颁发的证书,并消除不太安全的加密设置,包括 CBC MAC。Server 2012 R2 不支持带有 GCM 的 ECDHE_RSA,这意味着我们正在尝试使用基于 ECDH 的证书。但是,当我们允许使用带有 CBC-MAC 的密码套件(例如 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)和由同一 CA 颁发的 RSA 证书时,我们遇到了类似的问题。使用 GlobalSign 颁发的公共通配符证书,我们能够连接到所有浏览器。

企业 CA 和离线根 CA 均受信任,并且我们已验证它们正常运行。使用多个不同模板颁发给 2016 和 2019 服务器的证书在所有浏览器上均可正常运行。基于 ECDH 和 RSA 的模板在 2016+ 上同样运行良好。

ECDH 证书模板加密: ECDH 证书模板加密设置。

RSA 证书模板加密: RSA 证书模板加密设置。

2012 R2 服务器上的 RSA 和 ECDH 证书均被 Firefox 接受(一旦通过策略告知信任它们,并手动设置security.enterprise_roots.enabled),Pre-Chromium Edge、IE 和 Cygwin 的curlwget。我已经确认我们在注册表中使用了现代密码,并使用重新设置它们加密,并验证服务器提供的密码是否与 OpenSSL 和 nmap 兼容。同样,我已确认客户端确实能够使用这些密码进行连接。

Firefox 显示它正在与 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 连接,根据Qualys我们使用的 Chrome 版本支持此功能。

使用 ECDH

PORT    STATE SERVICE
443/tcp open  https
| ciphers:
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: A

每次我们尝试连接 Chrome 时,都会记录一对事件 36874/36888,表明客户端上不支持密码套件。

以下是我们在使用企业 CA 颁发的证书时遇到问题的密码套件列表,其中大多数仅用于测试(警告片段):

PORT    STATE SERVICE
443/tcp open  https
| ciphers:
|   SSLv3:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: C

我的问题是:

  1. 当服务器提供兼容的密码套件时,为什么基于 Chromium 的浏览器无法协商密码套件?
  2. 我需要设置什么才能允许 Server 2012 R2 使用内部颁发的证书?
  3. 除了将应用程序服务器升级到 2016/2019 之外,还有更好的方法来处理我正在尝试做的事情吗?目前,似乎完全禁用 TLS 并将所有内容置于 LB/反向代理之后可能是一个更好的主意,即使这些是单服务器解决方案。

编辑:我打开了一个Chromium 中的错误他们已确认服务器提供的密码套件应该可以被 Chrome 接受。在我提供通过 CHROME://Net-Export 捕获的网络日志后,他们现在正在调查。这可能与旧的Chrome/2012 错误。一旦 Google 报告了问题所在,我会再次更新此帖子。不过,目前看来我们这边的配置没有任何问题。

谢谢你的观看!

答案1

请确保您的证书签名请求 (CSR) 请求的证书不是仅对签名有效,而不是对签名和加密有效。如果 CSR 请求的证书仅对签名有效,并且您的 CA 的策略允许加密,即使请求仅是签名,那么您可能会看到此问题……有时。显然,仅请求签名的证书在用于加密时根本不起作用,但如果您的 CA 覆盖请求以允许加密,这将导致加密可以工作的情况,但仅限于客户端支持几个特定协议套件的情况下。识别导致此问题的证书很复杂。

尝试使用 wireshark 捕获 W2012 R2 和 Chrome 之间的流量。如果问题出在协议协商上,您将看到在客户端建议密码套件列表后,服务器立即重置连接。来自客户端的此数据包将包含“客户端 hello”的信息,随后立即收到来自服务器的 TCP RST(重置)。如果您深入了解“客户端 hello”数据包的详细信息,您将能够看到客户端建议的套件。

要解决此问题,您需要确保订购的证书用途正确(https://docs.microsoft.com/en-us/archive/blogs/pki/how-to-create-a-web-server-ssl-certificate-manually)。确保您的证书请求具有正确的参数(包括证书用途)至关重要。如果您使用的是带有 AD 集成模板的 Windows PKI,则可以根据需要在模板中对此进行“硬编码”。

答案2

Google 已确认这是 Chromium 处理 ClientHello 的方式、IIS 在 2012 上处理事物的方式以及我们的根 CA 的根证书签名中使用的算法存在的问题。

2012r2 上的 IIS 使用 ClientHello 检查链中的每个证书。Chrome 不会宣传,但确实支持根 CA 的 SHA-512 ECDH 证书。因此,当 IIS 针对整个证书链执行检查时,它会发现 Chrome 支持来自网络服务器的密码(来自我们的中间 CA),但不支持(诚然过度)P-521 ECDH 曲线,因此 IIS 重置了连接。Chrome 不会宣传对此的支持,以处理 TLS1.2/1.3 字段映射混乱中的边缘情况。

我在 Chromium 中提交的错误报告中的建议是更换根 CA,或者升级到 2016/2019,这样就不再存在这个问题了。

相关内容