gpt4 book ai didi

php - fwrite() : SSL operation failed with code 1. OpenSSL 错误消息:错误:1420C0CF:SSL 例程:ssl_write_internal:协议(protocol)已关闭

转载 作者:行者123 更新时间:2023-12-04 10:42:05 27 4
gpt4 key购买 nike

完整标题应为“PHP - 发送电子邮件:fwrite():SSL 操作失败,代码为 1。OpenSSL 错误消息:错误:1420C0CF:SSL 例程:ssl_write_internal:protocol is shutdown - 分析 stream_socket_enable_crypto 返回 false”。但这对于标题的 150 个字符来说太长了。

我们正在尝试在 PHP 脚本中发送电子邮件,我们得到

Warning: fwrite(): SSL operation failed with code 1. OpenSSL Error messages:error:1420C0CF:SSL routines:ssl_write_internal:protocol is shutdown in <...>/vendor/recolize/zendframework1/library/Zend/Mail/Protocol/Abstract.php on line 324 

如上所示,我们正在使用早已过时的 zendframework1 的改编版本,但这不是手头的问题,因为这适用于其他两个主机。

由于这个问题是不确定的,我们现在无法重现它。

但是,我们有一个允许进行一些分析的测试脚本,但我需要帮助理解可能是什么问题。

无需再费周折:

我们正在使用来自这个 stackoverflow 答案的脚本: How do I verify a TLS SMTP certificate is valid in PHP? - Answer 1

重要的部分是:
// Establish the connection
$smtp = fsockopen( "tcp://$server", 25, $errno, $errstr );
fread( $smtp, 512 );

// Here you can check the usual banner from $server (or in general,
// check whether it contains $server's domain name, or whether the
// domain it advertises has $server among its MX's.
// But yet again, Google fails both these tests.

fwrite($smtp,"HELO $myself\r\n");
fread($smtp, 512);

// Switch to TLS
fwrite($smtp,"STARTTLS\r\n");
fread($smtp, 512);
stream_set_blocking($smtp, true);
stream_context_set_option($smtp, 'ssl', 'verify_peer', true);
stream_context_set_option($smtp, 'ssl', 'allow_self_signed', true);
stream_context_set_option($smtp, 'ssl', 'capture_peer_cert', true);
stream_context_set_option($smtp, 'ssl', 'cafile', $cabundle);

// Necessary block to circumvent https://www.php.net/manual/en/function.stream-socket-enable-crypto.php#119122
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}

$secure = stream_socket_enable_crypto($smtp, true, $crypto_method);

// $secure = stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT );
var_dump($secure);
die;

建立一个套接字,设置为阻塞,设置 SSL 选项并尝试使用 PHP 的 stream_socket_enable_crypto 开始加密。 .

但是 stream_socket_enable_crypto 返回 bool(false) 并且没有信息为什么它失败。

目前我们怀疑是邮件服务器证书验证失败,但无法分析。

我们如何获得更多关于为什么 stream_socket_enable_crypto 返回 false 的信息?

编辑1:

修改了上面的代码块以反射(reflect) STREAM_CRYPTO_METHOD_TLS_CLIENT's specialty since PHP 5.6.7正如下面@Dilek 所述。谢谢你的回答!
遗憾的是,这并没有改变整体结果。 $secure 保持 bool(false)。

编辑2:

回应@Dilek 的更新:
$ php ssl_test.php
Array
(
[ssl] => Array
(
[verify_host] => 1
[verify_peer] => 1
[allow_self_signed] =>
[cafile] => /etc/ssl/cert.pem
)

)
failed to connect securely

我确保cafile存在:
$ ll /etc/ssl/cert.pem
0 lrwxrwxrwx 1 root wheel 38 Dec 19 11:09 /etc/ssl/cert.pem -> /usr/local/share/certs/ca-root.crt

并快速检查了它看起来不错的内容:
Certificate:
Data:
Version: ...
Serial Number:
...
Signature Algorithm: ...
Issuer: ...
...
Signature Algorithm: ...
-----BEGIN CERTIFICATE-----
MI...6EULg==
-----END CERTIFICATE-----

Certificate:
Data:
Version: ...
Serial Number:
...

etc.

最佳答案

PHP 错误:https://bugs.php.net/bug.php?id=69195

提交:https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0
STREAM_CRYPTO_METHOD_SSLv23_CLIENT使用不安全,因为在 php 5.6.7 之前,它表示 sslv2 或 sslv3。所以,你应该这样做:

$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;

if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}

stream_socket_enable_crypto($socket, true, $crypto_method);

您应该阅读相关链接的页面底部。

文档: https://www.php.net/manual/en/function.stream-socket-enable-crypto.php

更新:你的代码应该是这样的
            $smtp = fsockopen( "tcp://mail.domain.com", 25, $errno, $errstr );
fread( $smtp, 512 );
fwrite($smtp,"HELO worp\r\n");
fread($smtp, 512);
fwrite($smtp,"STARTTLS\r\n");
fread($smtp, 512);
stream_set_blocking($smtp, true);
stream_context_set_option($smtp, 'ssl', 'verify_host', true);
stream_context_set_option($smtp, 'ssl', 'verify_peer', true);
stream_context_set_option($smtp, 'ssl', 'allow_self_signed', false);

//Self signed certificates are blocked by googl and most servers

stream_context_set_option($smtp, 'ssl', 'cafile', '/etc/ssl/cacert.pem');
//you need to add correct and full path of CA file

//This is second solution in php documents in the link in question and in my answer
$secure = stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
stream_set_blocking($smtp, false);
print_r(stream_context_get_options($smtp));
if( ! $secure)
die("failed to connect securely\n");
print "Success!\n";

希望这对您有所帮助。

关于php - fwrite() : SSL operation failed with code 1. OpenSSL 错误消息:错误:1420C0CF:SSL 例程:ssl_write_internal:协议(protocol)已关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59874613/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com