如何仅支持 TLS 1.x(在我的网络服务中)?

How do I support TLS 1.x only (in my webservice)?

我试图通过使用 TIdServerIOHandlerSSLOpenSSL 组件并设置其 SSLOptions.Method 和 [=15= 来控制与我的网络服务的 HTTPS 连接支持哪些 TLS/SSL 协议] 属性(如 中所建议)。

默认是方法sslvTLSv1和SSLVersions[sslvTLSv1](方法和SSLVersions的关系见this answer):

我将 nmap 与 this answer 中的 ssl-enum-ciphers.nse 脚本一起使用来检查实际可用的内容,并获得此脚本输出:

| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A
|       TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Ciphersuite uses MD5 for message integrity
|       Weak certificate signature: SHA1
|_  least strength: C

但是缺少 TLS 1.1 和 TLS 1.2。

如果我将 Method 设置为 sslvSSLv23 (" 允许在客户端和服务器支持不同 SSL/TLS 版本的情况下进行动态版本协商的通配符。它允许他们弄清楚并使用双方共同的最高版本" (source)) 我看到 sslvSSLv2sslvSSLv3 变得活跃。
但我不希望 SSL 2.0(deprecated/prohibited 在 2011 年被 RFC 6176 支持)和 3.0(在 2015 年 6 月被 RFC 7568 弃用)支持 (source).
我无法从方法 sslvSSLv23 生成的集合中减去 sslvTLSv2sslvTLSv3:我们恢复到仅支持 TLS 1.0 的默认配置。

请注意,如果我 'only' 遗漏了 sslvTLSv2(方法是 sslvSSLv23 并且 SSLVersions 是 [sslvSSLv3,sslvTLSv1]),nmap 会告诉我:

| ssl-enum-ciphers:
|   SSLv3:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A
|       TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       CBC-mode cipher in SSLv3 (CVE-2014-3566)
|       Ciphersuite uses MD5 for message integrity
|       Weak certificate signature: SHA1
|   TLSv1.0:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A
|       TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Ciphersuite uses MD5 for message integrity
|       Weak certificate signature: SHA1
|   TLSv1.1:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A
|       TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Ciphersuite uses MD5 for message integrity
|       Weak certificate signature: SHA1
|       Weak cipher RC4 in TLSv1.1 or newer not needed for BEAST mitigation
|   TLSv1.2:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - A
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - A
|       TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Ciphersuite uses MD5 for message integrity
|       Weak certificate signature: SHA1
|       Weak cipher RC4 in TLSv1.1 or newer not needed for BEAST mitigation
|_  least strength: C

我该怎么做才能仅支持所有 TLS 1.x 版本?

这是 Delphi XE2 with Indy 10.5.8.0,运行ning on Win7,使用 OpenSSL 1.02f 测试。使用 OpenSSL 1.02g,我得到 ,我们还没有准备好更新到 Delphi 西雅图(更新 1),在 Indy 代码中解决了这个问题。

补充说明:

    EIdOSSLAcceptError 'Error accepting connection with SSL. EOF was observed that violates the protocol.'
    EIdOSSLUnderlyingCryptoError in ssl3_get_client_hello:no shared cipher
    EIdOSSLUnderlyingCryptoError in ssl3_get_client_hello:wrong version number

But TLS 1.1 and TLS 1.2 are missing.

是的,因为如果您将 Method 设置为 sslvTLSv1,Indy 将仅专门使用 TLS 1.0。

您的 Object Inspector 屏幕截图清楚地表明您正在使用不支持 TLS 1.1+ 的 Indy 版本(如果支持,将有 sslvTLSv1_1sslvTLSv1_2 选项可用SSLVersions 属性).

Note that if I 'only' leave out sslvTLSv2 (Method is sslvSSLv23 and SSLVersions is [sslvSSLv3,sslvTLSv1]), nmap tells me:

MethodsslvSSLv23 时,Indy 仅禁用不需要的 SSL/TLS 版本,在本例中为 SSLv2。您显然正在使用支持 TLS 1.1+ 的 OpenSSL 库版本。因此,因为您的 Indy 版本不支持 TLS 1.1+,所以不会禁用它们。默认情况下启用它们。由于您没有禁用 TLS 1.0,TLS 1.1+ 将由 OpenSSL 本身隐式启用。

What can I do so that only all TLS 1.x versions are supported?

这是一个有点奇怪的解决方法,但您可以将 SSLVersions 设置为 [sslvSSLv23,sslvTLSv1]。这会将 Method 设置为 sslvSSLv23 并从 SSLVersions 中删除 sslvSSLv23。这样,Indy 将使用 SSLv23 通配符并禁用 SSLv2 和 SSLv3,同时启用 TLS 1.0+。

不幸的是,您无法在设计时在对象检查器中真正进行此配置。好吧,你可以(先只启用 sslvTLSv1,然后再启用 ssvSSLv23),但它不会正确保存在 DFM 中(SSLVersions 将被省略,因为 [sslvTLSv1] 是默认值),因此最终会在 运行 时重新启用 SSLv2 和 SSLv3。为避免这种情况,您必须在 运行 时在代码中分配 SSLVersions,然后再激活您的服务器:

IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvSSLv23,sslvTLSv1];

否则,替代方法是升级到本机支持 TLS 1.1+ 的最新版本的 Indy,然后您只需将 SSLVersions 设置为 [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2](在 运行-时间或设计时间)并继续。