TIdServerIOHandlerSSLOpenSSL.SSLOptions.CipherList中的密码名称顺序是否重要?

时间:2016-04-01 10:21:57

标签: delphi ssl openssl indy

我限制了我的网络服务只允许这些TLS 1.x密码的密码:

    TLS_RSA_WITH_AES_128_CBC_SHA
    TLS_RSA_WITH_AES_128_CBC_SHA256
    TLS_RSA_WITH_AES_128_GCM_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA
    TLS_RSA_WITH_AES_256_CBC_SHA256
    TLS_RSA_WITH_AES_256_GCM_SHA384
    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
    TLS_RSA_WITH_IDEA_CBC_SHA
    TLS_RSA_WITH_RC4_128_MD5
    TLS_RSA_WITH_RC4_128_SHA

更新以回复Dave Thompson的评论:

我现在按顺序获取this SO answer生成的密码 因为我们目前使用的是Delphi XE2 / Indy 10.5.8.0/OpenSSL 1.0.2f,所以我省略了ECDHE密码,这些密码是too cumbersome to implement with these software versions。 此外,我们仍然允许TLS 1.0 在更新到Delphi Seattle 10之后,我们将禁止使用TLS 1.0并将ECDHE密码重新放入。

这留下:

TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc15)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x67)
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 (0xc4)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33)
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x88)
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x45)

转换为OpenSSL名称(根据Mapping OpenSSL cipher suite names to RFC names),这些是:

DHE-RSA-CHACHA20-POLY1305 
DHE-RSA-AES256-GCM-SHA384 
DHE-RSA-AES128-GCM-SHA256 
DHE-RSA-AES256-SHA256 
DHE-RSA-AES128-SHA256 
- cannot find the equivalent for 0xc4 - anyone? -
DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA 
DHE-RSA-CAMELLIA256-SHA 
DHE-RSA-CAMELLIA128-SHA256

服务器提供密码的顺序很重要,但我是否可以控制此顺序? CipherList是一个字符串属性,包含与'+'连接的这些名称:

TIdServerIOHandlerSSLOpenSSL.SSLOptions.CipherList := 'DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SH:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CAMELLIA128-SHA256';

如果是,推荐的订单是什么?

请注意,由于我的webservice是服务器,因此我设置了SSLOptions.Mode := sslmServer

*这些nmap脚本ssl-enum-ciphers成绩为'A'

2 个答案:

答案 0 :(得分:5)

  

TIdServerIOHandlerSSLOpenSSL.SSLOptions.CipherList中的密码名称顺序是否重要?

主要是。

TLS 指定谁决定密码。通常,服务器尊重客户的偏好。也就是说,服务器将使用客户端的第一个首选项(如果可用并启用),或者客户端的第二个首选项(如果可用并启用)等等。

大多数库允许服务器覆盖行为。例如,使用OpenSSL,SSL_OP_CIPHER_SERVER_PREFERENCE选项。在这种情况下,服务器将匹配服务器的第一个首选项(如果客户端通告它),服务器的第二个首选项(如果客户端通告它),等等。

对于我控制的服务器,我调整密码套件列表并通常设置SSL_OP_CIPHER_SERVER_PREFERENCE,因为许多客户端不关注细节。他们只是在ClientHello中扔掉了密码套装的汤,希望能有些东西粘在上面。

  

服务器提供密码的顺序很重要,但我是否可以控制此顺序?

在服务器上,确定密码套件的顺序,然后使用SSL_CTX_set_cipher_listSSL_set_cipher_list进行设置。通过设置列表,确保即使是客户端的第一选择(假设您省略它),也不会使用RC4-MD5。为了获得最大的影响,还要设置SSL_OP_CIPHER_SERVER_PREFERENCE上下文选项。

另见How do I disable a particular cipher suite in openssl?上下文是OpenSSL,但它应该让你知道Delphi的去处。

  

(评论):您的回答中我不清楚:CipherList属性是否已经表示订单?如果我查看底层的Delphi / Indy代码,我发现它只是外部函数的包装器SSL_CTX_set_cipher_list : function(_para1: PSSL_CTX; const str: PAnsiChar): TIdC_INT cdecl = nil; in IdSSLOpenSSLHeaders.pas

如果我正确理解Delphi,那么我相信答案是肯定的,确实如此。但它可能使用(1)OpenSSL的默认列表,或(2)Delphi默认列表。两者都可能是 "ALL:!EXP:!LOW" 或类似的东西。在任何一种情况下,您都需要根据自己的喜好进行调整。

如果您对列表中的列表感兴趣,请使用Wireshark检查 ClientHello 。使用s_client很容易生成一个,它会显示OpenSSL的默认密码套件列表:

$ openssl s_client -connect www.ietf.org:443 -tls1 -servername www.ietf.org

相应的Wireshark跟踪包含55个默认密码套件:

enter image description here

您还可以使用-cipher选项和 "HIGH:!aNULL:!MD5:!RC4" 来改善安全状况并减少密码套件的数量。密码套数将减少到约35个。

 $ openssl s_client -connect www.ietf.org:443 -tls1 -servername www.ietf.org \
     -cipher 'HIGH:!aNULL:!MD5:!RC4'

如果您不喜欢TripleDES和Cameilla,那么您可以将其减少到大约20个密码套件:

$ openssl s_client -connect www.ietf.org:443 -tls1 -servername www.ietf.org \
    -cipher 'HIGH:!aNULL:!MD5:!RC4:!3DES:!CAMELLIA'

现在,假设客户端仅配置了RC4-MD5,并且服务器仅配置了AES-GCM。即,客户端和服务器之间没有密码套件的交集。在这种情况下,您将在OpenSSL中收到错误。错误将是0x1408A0C1,“没有共享密码套件”。它在服务器上看起来像这样:

140339533272744:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1353

对于基于OpenSSL的客户端和服务器,您可以使用“DEFAULT”字符串确定默认密码套件列表。这就是它所谓的(检查ciphers(1) man page)。

其中有103个,其中包括弱和受伤的算法。在实践中,您希望将其配对至16个左右您认为习惯使用的密码套件(即您的安全状况):

$ openssl ciphers -v 'DEFAULT' | cut -f 1 -d " " | wc -l
     103

$ openssl ciphers -v 'DEFAULT' | cut -f 1 -d " "
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
SRP-DSS-AES-256-CBC-SHA
SRP-RSA-AES-256-CBC-SHA
SRP-AES-256-CBC-SHA
DH-DSS-AES256-GCM-SHA384
DHE-DSS-AES256-GCM-SHA384
DH-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-SHA256
DHE-DSS-AES256-SHA256
DH-RSA-AES256-SHA256
DH-DSS-AES256-SHA256
DHE-RSA-AES256-SHA
DHE-DSS-AES256-SHA
DH-RSA-AES256-SHA
DH-DSS-AES256-SHA
DHE-RSA-CAMELLIA256-SHA
DHE-DSS-CAMELLIA256-SHA
DH-RSA-CAMELLIA256-SHA
DH-DSS-CAMELLIA256-SHA
ECDH-RSA-AES256-GCM-SHA384
ECDH-ECDSA-AES256-GCM-SHA384
ECDH-RSA-AES256-SHA384
ECDH-ECDSA-AES256-SHA384
ECDH-RSA-AES256-SHA
ECDH-ECDSA-AES256-SHA
AES256-GCM-SHA384
AES256-SHA256
AES256-SHA
CAMELLIA256-SHA
PSK-AES256-CBC-SHA
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
SRP-DSS-AES-128-CBC-SHA
SRP-RSA-AES-128-CBC-SHA
SRP-AES-128-CBC-SHA
DH-DSS-AES128-GCM-SHA256
DHE-DSS-AES128-GCM-SHA256
DH-RSA-AES128-GCM-SHA256
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256
DHE-DSS-AES128-SHA256
DH-RSA-AES128-SHA256
DH-DSS-AES128-SHA256
DHE-RSA-AES128-SHA
DHE-DSS-AES128-SHA
DH-RSA-AES128-SHA
DH-DSS-AES128-SHA
DHE-RSA-SEED-SHA
DHE-DSS-SEED-SHA
DH-RSA-SEED-SHA
DH-DSS-SEED-SHA
DHE-RSA-CAMELLIA128-SHA
DHE-DSS-CAMELLIA128-SHA
DH-RSA-CAMELLIA128-SHA
DH-DSS-CAMELLIA128-SHA
ECDH-RSA-AES128-GCM-SHA256
ECDH-ECDSA-AES128-GCM-SHA256
ECDH-RSA-AES128-SHA256
ECDH-ECDSA-AES128-SHA256
ECDH-RSA-AES128-SHA
ECDH-ECDSA-AES128-SHA
AES128-GCM-SHA256
AES128-SHA256
AES128-SHA
SEED-SHA
CAMELLIA128-SHA
IDEA-CBC-SHA
PSK-AES128-CBC-SHA
ECDHE-RSA-RC4-SHA
ECDHE-ECDSA-RC4-SHA
ECDH-RSA-RC4-SHA
ECDH-ECDSA-RC4-SHA
RC4-SHA
RC4-MD5
PSK-RC4-SHA
ECDHE-RSA-DES-CBC3-SHA
ECDHE-ECDSA-DES-CBC3-SHA
SRP-DSS-3DES-EDE-CBC-SHA
SRP-RSA-3DES-EDE-CBC-SHA
SRP-3DES-EDE-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-DSS-DES-CBC3-SHA
DH-RSA-DES-CBC3-SHA
DH-DSS-DES-CBC3-SHA
ECDH-RSA-DES-CBC3-SHA
ECDH-ECDSA-DES-CBC3-SHA
DES-CBC3-SHA
PSK-3DES-EDE-CBC-SHA
EDH-RSA-DES-CBC-SHA
EDH-DSS-DES-CBC-SHA
DH-RSA-DES-CBC-SHA
DH-DSS-DES-CBC-SHA
DES-CBC-SHA

答案 1 :(得分:2)

Meta:不是问题的答案,而是对评论的回应。要真正理解' SSL / TLS不是真正的编程,并且是一个可能过于宽泛的大问题。对于SO。但无论如何还是有些想法:

  • 作为标准化协议的SSL / TLS的权威指南,或者它们的真正系列,当然是定义它们的RFC,加上适用的那些RFC引用的外部标准(如用于AES的FIPS 197,用于RSA的PKCS#1,用于ECC的SECG1等)。 Wikipedia有一个很好的概述和(AFAICT)完整的参考文献列表。

  • 如果你只想大致了解这些作品是什么以及它们是如何工作的(比如RSA vs DHE vs ECDHE,AES vs TDES或HMAC vs AEAD)维基百科也很好,规范Q& as security.SE

  • 中间人可能是 Ivan Ristic的新'防弹'书;他是广泛使用且备受推崇的SSLLabs测试背后的人,本书与from that homepage相关联。我还没看过实际的书,但几年前他在博客上展示并讨论了计划书中的一些材料,我认为这看起来很棒。

另外,您没有直接实施标准;您使用的是OpenSSL版本的实现,并且在当今的软件生态系统中 OpenSSL可能会有所不同。首先,OpenSSL本身有许多构建(也称为编译时)选项。我只是在大纲中了解Delphi而且我不知道您识别的OpenSSL版本是为Delphi(或Indy?)提供的,还是为了Delphi(或者'来自操作系统或其他地方,以及在任何情况下使用什么选项甚至可能修改(补丁)构建它。 (为了进行比较,我通常使用基于RedHat和Debian的Linux来支持补丁,以便识别为例如' 1.0.1e'的软件包通常与其他版本不同,有时也是如此。标识为' 1.0.1e'。)