Cro*_*nos 8 php ssl php-openssl
我尝试通过连接fsockopen到sendm.cert.legalmail.it的465端口,是在意大利被称为PEC SMTPS服务.
使用任何版本的PHP我都试过这个片段工作:
<?php
fsockopen('tls://sendm.cert.legalmail.it', 465);
Run Code Online (Sandbox Code Playgroud)
一切都没问题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
Run Code Online (Sandbox Code Playgroud)
所以OpenSSL 1.0.2j我尝试通过命令行连接:
openssl s_client -connect sendm.cert.legalmail.it:465
Run Code Online (Sandbox Code Playgroud)
它完美地运作.
我尝试使用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)
Run Code Online (Sandbox Code Playgroud)
只有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
Run Code Online (Sandbox Code Playgroud)
随着版本 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
Run Code Online (Sandbox Code Playgroud)
并且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
Run Code Online (Sandbox Code Playgroud)
好吧,经过一番研究我找到了原因:
PHP 有一个OPENSSL_DEFAULT_STREAM_CIPHERS包含 openssl 的默认查询,使用以下命令:
openssl ciphers -v `php -r 'echo OPENSSL_DEFAULT_STREAM_CIPHERS;'`
Run Code Online (Sandbox Code Playgroud)
我得到了 PHP 可以在当前安装的 openssl 版本下处理的所有密码。
在同一查询返回不同密码之间1.0.2h,1.0.2j列出了对这些密码的删除支持:
EDH-RSA-DES-CBC3-SHADES-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
);
Run Code Online (Sandbox Code Playgroud)