草庐IT

PHP 握手失败 TLS1.0

coder 2024-01-02 原文

我尝试通过 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 测试过。

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

更新 如果我总是用 ./testssl.sh -E sendm.cert.legalmail.it:465OpenSSL 1.0.2j< 查看="">返回:

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.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
);

关于PHP 握手失败 TLS1.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40867007/

有关PHP 握手失败 TLS1.0的更多相关文章

  1. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  2. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  3. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  4. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  5. ruby-on-rails - Ruby 的 'open_uri' 是否在读取或失败后可靠地关闭套接字? - 2

    一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我

  6. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  7. ruby - gem 规范失败 - 2

    我正在为毕业设计开发GEM,TravisCI构建不断失败。这是我在Travis上的链接:https://travis-ci.org/ricardobond/perpetuus/builds/8709218构建错误是:$bundleexecrakerakeaborted!Don'tknowhowtobuildtask'default'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_wrapper:14:in`eval'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_

  8. ruby-on-rails - "rails generate rspec:install"似乎失败了 - 2

    运行:ruby1.9.3p0和Rails3.2.1尝试使用rspec但当我尝试将其安装到我的应用程序中时出现以下错误:/Users/Si/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.1/lib/rails/railtie/configuration.rb:85:in`method_missing':undefinedmethod`generators'for#(NoMethodError)from/Users/Si/.rvm/gems/ruby-1.9.3-p0/gems/rspec-rails-2.0.0.beta.18/lib/rspec-r

  9. ruby - Date 与 nil 的比较失败 - ruby - 2

    我正在运行这样的代码:ifvalid_from>Date.today当我运行它时,我得到一个错误提示comparisonofDatewithnilfailed我假设它正在发生,因为在某些情况下valid_from是nil。有没有办法避免出现此错误? 最佳答案 你可以这样做:ifvalid_fromandvalid_from>Date.today...end这将在第一个子句上短路,因为valid_from为nil,因此为false。 关于ruby-Date与nil的比较失败-ruby,我们

  10. ruby-on-rails - ActiveRecord 验证失败后如何将内容保存到数据库? - 2

    基本上我想要做的是在MyModelLog表中记录对MyModel的操作。这是一些伪代码:classMyModel我也有一个看起来像这样的模型:classMyModelLog"somethinghappened")endend为了记录我尝试:在MyModel的something方法中添加MyModelLog.log_something在MyModel的after_validation回调上调用MyModelLog.log_something在这两种情况下,创建都会在验证失败时回滚,因为它在验证事务中。当然我也想在验证失败时记录。我真的不想登录文件或数据库以外的其他地方,因为我需要日志条目

随机推荐