【问题标题】:How do I support TLS 1.x only (in my webservice)?如何仅支持 TLS 1.x(在我的网络服务中)?
【发布时间】:2016-03-31 12:23:19
【问题描述】:

我正在尝试通过使用TIdServerIOHandlerSSLOpenSSL 组件并设置其SSLOptions.MethodSSLOptions.SSLVersions 属性(如this answer 中的建议)来控制与我的Web 服务的HTTPS 连接支持哪些TLS/SSL 协议.

默认为 Method sslvTLSv1 和 SSLVersions [sslvTLSv1](有关 Method 和 SSLVersions 之间的关系,请参阅 this answer):

我使用 nmap 和来自 this answerssl-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(2011 年被 RFC 6176 弃用/禁止)和 3.0(2015 年 6 月被 RFC 7568 弃用)支持 (source)。
我无法从方法 sslvSSLv23 生成的集合中同时减去 sslvTLSv2sslvTLSv3:我们恢复到仅支持 TLS 1.0 的默认配置。

请注意,如果我“只”省略了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 版本?

这是带有 Indy 10.5.8.0 的 Delphi XE2,在 Win7 上运行,使用 OpenSSL 1.02f 进行测试。使用 OpenSSL 1.02g 我得到了this issue,我们还没有准备好更新到 Delphi Seattle(更新 1),在 Indy 代码中解决了这个问题。

补充说明:

  • 我是否也应该放弃 TLS 1.0 支持?

  • SSLOptions.Mode 仍然是默认的sslmUnassigned,我想稍后再看。

  • 请注意,nmap 脚本仅测试 SSLv3/TLS 版本,而不是 SSLv2。我还使用了SSLScan,这表明如果我只省略sslvTLSv3,SSL2 确实仍然启用;-(

  • 忘记有关弱密码的信息,这是接下来要解决的问题 ;-)

  • 如果我在 Delphi IDE 中运行我的 web 服务,我实际上无法进行 nmap 测试,这会产生各种运行时错误(如果我运行可执行文件则不会出现)。也许这些应该发生,因为 nmap 脚本正在触发各种测试?

EIdOSSLAcceptError '接受与 SSL 的连接时出错。观察到 EOF 违反了协议。 ssl3_get_client_hello 中的 EIdOSSLUnderlyingCryptoError:没有共享密码 ssl3_get_client_hello 中的 EIdOSSLUnderlyingCryptoError:错误的版本号

【问题讨论】:

    标签: delphi ssl openssl delphi-xe2 indy


    【解决方案1】:

    但是缺少 TLS 1.1 和 TLS 1.2。

    对,因为如果您将Method 设置为sslvTLSv1,Indy 将只专门使用 TLS 1.0。

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

    请注意,如果我“只”省略了 sslvTLSv2(方法是 sslvSSLv23,SSLVersions 是 [sslvSSLv3,sslvTLSv1]),nmap 会告诉我:

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

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

    这有点奇怪,但您可以将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](在运行时或设计时)继续前进。

    【讨论】:

    • 谢谢雷米,这行得通。幸运的是,我已经在运行时做了所有事情。我们还在努力在不久的将来将所有东西从 XE2 升级到西雅图。
    猜你喜欢
    • 2016-08-29
    • 2021-06-27
    • 2017-06-26
    • 1970-01-01
    • 2014-01-30
    • 2014-06-12
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多