PHP握手失败TLS1.0
我尝试通过fsockopen连接到465端口上的sendm.cert.legalmail.it,是意大利的名为PEC的SMTPS服务.
使用任何版本的PHP我都试过这个片段工作: <?php fsockopen('tls://sendm.cert.legalmail.it',465); 所有这一切都可以使用OpenSSL 1.0.2h,如果我升级到OpenSSL 1.0.2j这个代码片段失败并出现此错误: 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强制握手到TLS1:’tlsv1.0 :: //sendm.cert.legalmail.it’但结果是一样的. 我在Ubuntu 16.04上,使用PHP5.6和PHP7.1进行测试. 这个bug在哪里?在openssl?在PHP?在服务器握手? 更新,如果我总是使用./testssl.sh -E sendm.cert.legalmail.it:465与OpenSSL 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有一个OPENSSL_DEFAULT_STREAM_CIPHERS,它包含openssl的默认查询,使用以下命令: openssl ciphers -v `php -r 'echo OPENSSL_DEFAULT_STREAM_CIPHERS;'` 我得到了PHP可以安装的当前版本的openssl所能处理的所有密码. 在1.0.2h和1.0.2j之间,相同的查询返回不同的密码列出了对这些的支持: > EDH-RSA-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 ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |