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

时间:2016-03-31 12:23:20

标签: delphi ssl openssl delphi-xe2 indy

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

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

enter image description here

我使用来自this answerssl-enum-ciphers.nse脚本的nmap来检查实际可用的内容,并获取此脚本输出:

| 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)。 我无法从方法sslvTLSv2生成的集合中减去sslvTLSv3sslvSSLv23:我们将恢复为仅支持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(Update 1),在这里用Indy代码解决了这个问题。

附加说明:

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

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

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

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

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

    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

1 个答案:

答案 0 :(得分:1)

  

但缺少TLS 1.1和TLS 1.2。

是的,因为如果你将Method设置为sslvTLSv1,Indy将只使用TLS 1.0。

您的对象检查器的屏幕截图清楚地显示您使用的是不支持TLS 1.1+的Indy版本(如果有的话,sslvTLSv1_1sslvTLSv1_2选项可用{ {1}}属性)。

  

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

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

  

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

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

不幸的是,您无法在设计时在Object Inspector中进行此配置。好吧,您可以(先启用SSLVersions,然后再启用sslvTLSv1),但不能正确保存在DFM中(ssvSSLv23将被省略,因为{ {1}}是默认值),因此最终会在运行时重新启用SSLv2和SSLv3。为避免这种情况,在激活服务器之前,您必须在运行时在代码中分配SSLVersions

[sslvTLSv1]

否则,另一种方法是升级到本机支持TLS 1.1+的最新版本的Indy,然后您可以将SSLVersions设置为IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvSSLv23,sslvTLSv1]; (在运行时或设计时间)并继续前进。