【问题标题】:PHP handshake fail TLS1.0PHP握手失败TLS1.0
【发布时间】:2017-04-13 12:22:24
【问题描述】:

我尝试通过fsockopen 连接到sendm.cert.legalmail.it 上的465 端口,这是意大利称为PEC 的SMTPS 服务。

对于任何版本的 PHP,我都尝试过这个 sn-p 工作:

<?php
fsockopen('tls://sendm.cert.legalmail.it', 465);

OpenSSL 1.0.2h 没问题,如果我升级到OpenSSL 1.0.2j,这个 sn-p 会因为这个错误而失败:

    PHP Warning:  fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
    error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure in ~/Development/experimental/php-handshake/connect.php on line 3
    PHP Warning:  fsockopen(): Failed to enable crypto in ~/Development/experimental/php-handshake/connect.php on line 3
    PHP Warning:  fsockopen(): unable to connect to tls://sendm.cert.legalmail.it:465 (Unknown error) in ~/Development/experimental/php-handshake/connect.php on line 3

所以使用OpenSSL 1.0.2j 我尝试通过命令行连接:

openssl s_client -connect sendm.cert.legalmail.it:465

效果很好。

我尝试使用testssl 检查服务器上的 SSL,这是转储(已剥离):

SSLv2               not offered (OK)
SSLv3               not offered (OK)
TLS 1               offered
TLS 1.1             not offered
TLS 1.2             not offered
Version tolerance   downgraded to TLSv1.0 (OK)

只有TLS 1 可用,我尝试使用此uri:'tlsv1.0:://sendm.cert.legalmail.it' 强制与TLS1 握手,但结果相同。

我在 Ubuntu 16.04 上,使用 PHP5.6 和 PHP7.1 进行了测试。

错误在哪里?在openssl?在 PHP 中?在服务器握手?

更新如果我总是用./testssl.sh -E sendm.cert.legalmail.it:465OpenSSL 1.0.2j 来查看 Chiper,返回:

x05     RC4-SHA                           RSA        RC4       128      TLS_RSA_WITH_RC4_128_SHA                           
x04     RC4-MD5                           RSA        RC4       128      TLS_RSA_WITH_RC4_128_MD5                           
x16     EDH-RSA-DES-CBC3-SHA              DH 1024    3DES      168      TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA                  
x0a     DES-CBC3-SHA                      RSA        3DES      168      TLS_RSA_WITH_3DES_EDE_CBC_SHA                      
x15     EDH-RSA-DES-CBC-SHA               DH 1024    DES       56       TLS_DHE_RSA_WITH_DES_CBC_SHA                       
x09     DES-CBC-SHA                       RSA        DES       56       TLS_RSA_WITH_DES_CBC_SHA                           
x14     EXP-EDH-RSA-DES-CBC-SHA           DH(512)    DES       40,exp   TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA              
x08     EXP-DES-CBC-SHA                   RSA(512)   DES       40,exp   TLS_RSA_EXPORT_WITH_DES40_CBC_SHA                  
x06     EXP-RC2-CBC-MD5                   RSA(512)   RC2       40,exp   TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5                 
x03     EXP-RC4-MD5                       RSA(512)   RC4       40,exp   TLS_RSA_EXPORT_WITH_RC4_40_MD5      

使用版本OpenSSL 1.0.2h

x05     RC4-SHA                           RSA        RC4       128       
x04     RC4-MD5                           RSA        RC4       128       
x16     EDH-RSA-DES-CBC3-SHA              DH 1024    3DES      168       
x0a     DES-CBC3-SHA                      RSA        3DES      168

而且 php const OPENSSL_DEFAULT_STREAM_CIPHERS 在它包含的所有版本中都是相同的:

ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!SSLv2:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!RC4:!ADH

【问题讨论】:

    标签: php ssl php-openssl


    【解决方案1】:

    完全编辑答案:在此处查看答案HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK

    这可能是 fsock 和 curl 的原因。 虽然他的问题是关于 windows / xampp,但我想它会有所帮助,我想升级操作系统的人没有将 php.ini 与新版本合并

    【讨论】:

    • 但这个问题与证书验证无关,它在握手时失败。
    【解决方案2】:

    好的,经过一番研究,我找到了原因:

    PHP 有一个 OPENSSL_DEFAULT_STREAM_CIPHERS,其中包含对 openssl 的默认查询,使用以下命令:

    openssl ciphers -v `php -r 'echo OPENSSL_DEFAULT_STREAM_CIPHERS;'`
    

    我得到了 PHP 可以在安装了当前版本的 openssl 的情况下处理的所有密码。

    1.0.2h1.0.2j 之间,相同的查询返回不同的密码,列出对这些的删除支持:

    1. EDH-RSA-DES-CBC3-SHA
    2. DES-CBC3-SHA

    所以默认情况下 PHP 不能正确处理连接,但如果我用这个密码强制 $context 连接发生:

    $context = stream_context_create(
        [
            'ssl' => [
                'ciphers' => 'EDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA',
            ],
        ]
    );
    
    $fp = stream_socket_client(
      'tls://sendm.cert.legalmail.it:465',
      $errno,
      $errstr,
      30,
      STREAM_CLIENT_CONNECT,
      $context
    );
    

    【讨论】:

      【解决方案3】:

      对于遇到同样问题的其他人:Legalmail TLS 服务器现在似乎支持 TLSv1.2,所以这对他们来说不再是问题了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-19
        • 2018-07-28
        • 2017-06-19
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多