как исправить сбой проверки сертификата SSL

Я использую PHPMailer вместе с Apache и PHP локально. Когда я тестирую свою конфигурацию SSL и свои cacerts, я получаю

default_cert_file = C:\Program Files\Common Files\SSL/cert.pem
default_cert_file_env = SSL_CERT_FILE
default_cert_dir = C:\Program Files\Common Files\SSL/certs
default_cert_dir_env = SSL_CERT_DIR
default_private_dir = C:\Program Files\Common Files\SSL/private
default_default_cert_area = C:\Program Files\Common Files\SSL
ini_cafile = 
ini_capath = 

а потом я делаю

 var_dump(fsockopen("smtp.gmail.com", 465, $errno, $errstr, 3.0));
 var_dump($errno);
 var_dump($errstr);

и я получаю

fsockopen resource(2) of type (stream) int(0) string(0) "" 

В моем php.ini у меня curl.cainfo = C:/php/cacert.pem в части curl и он работает.

Но когда я пытаюсь использовать PHPMailer для отправки почты с localhost, я продолжаю получать

SSL operation failed with code 1. OpenSSL Error messages:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed 
Failed to enable crypto
unable to connect to ssl://smtp.gmail.com:465 (Unknown error)

Я также зашел в учетную запись, используемую в SMTP, в https://accounts.google.com/DisplayUnlockCaptcha и включил ее. И https://myaccount.google.com/lesssecureapps?pli=1 и включили менее защищенные приложения. Я предполагаю, что это ошибка SSL, а не PHPMailer. Честно говоря, я сбит с толку, не знаю, как это исправить. Извините за мое незнание, любая помощь о том, что не так и как это исправить, была бы замечательной.

PS, это мой php файл, который отправляет почту. Спасибо

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;    
require 'C:/php/PHPMailer/src/Exception.php';
require 'C:/php/PHPMailer/src/PHPMailer.php';
require 'C:/php/PHPMailer/src/SMTP.php';

$mail = new PHPMailer(true);                             
try {

    $mail->SMTPDebug = 3;
    $mail->isSMTP();                                      
    $mail->Host = 'smtp.gmail.com'; 
    $mail->SMTPAuth = true;                               
    $mail->Username = '[email protected]';                 
    $mail->Password = 'secret';                           
    $mail->SMTPSecure = 'ssl';                            
    $mail->Port = 465;                                    

    //Recipients
    $mail->setFrom('[email protected]');
    $mail->addAddress('[email protected]');     


    //Content
    $mail->isHTML(true);                                 
    $mail->Subject = 'subject';
    $mail->Body    = 'HTML message body <b>in bold!</b>';
    $mail->AltBody = 'body in plain text';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
}            
?>

Обновить

Когда я пытаюсь использовать $mail->SMTPSecure = 'ssl'; и $mail->Port = 465;, я получаю

2017-10-01 13:04:25 Connection: opening to ssl://smtp.gmail.com:465, timeout=300, options=array()
2017-10-01 13:04:26 Connection failed. Error #2: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed [C:\php\PHPMailer\src\SMTP.php line 324]
2017-10-01 13:04:26 Connection failed. Error #2: stream_socket_client(): Failed to enable crypto [C:\php\PHPMailer\src\SMTP.php line 324]
2017-10-01 13:04:26 Connection failed. Error #2: stream_socket_client(): unable to connect to ssl://smtp.gmail.com:465 (Unknown error) [C:\php\PHPMailer\src\SMTP.php line 324]
2017-10-01 13:04:26 SMTP ERROR: Failed to connect to server: (0)
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
Message could not be sent.Mailer Error: SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

Когда я пытаюсь использовать $mail->SMTPSecure = 'tls'; и $mail->Port = 587;, я получаю

2017-10-01 13:07:20 Connection: opening to smtp.gmail.com:587, timeout=300, options=array()
2017-10-01 13:07:21 Connection: opened
2017-10-01 13:07:21 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP l4sm5217189wrb.74 - gsmtp
2017-10-01 13:07:21 CLIENT -> SERVER: EHLO localhost
2017-10-01 13:07:21 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [85.75.196.114]250-SIZE 35882577250-8BITMIME250-STARTTLS250-ENHANCEDSTATUSCODES250-PIPELINING250 SMTPUTF8
2017-10-01 13:07:21 CLIENT -> SERVER: STARTTLS
2017-10-01 13:07:21 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
2017-10-01 13:07:21 Connection failed. Error #2: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed [C:\php\PHPMailer\src\SMTP.php line 403]
SMTP Error: Could not connect to SMTP host.
2017-10-01 13:07:21 CLIENT -> SERVER: QUIT
2017-10-01 13:07:21 SERVER -> CLIENT: 
2017-10-01 13:07:21 SMTP ERROR: QUIT command failed: 
2017-10-01 13:07:21 Connection: closed
SMTP Error: Could not connect to SMTP host.
Message could not be sent.Mailer Error: SMTP Error: Could not connect to SMTP host.

person slevin    schedule 01.10.2017    source источник
comment
fsockopen просто открывает TCP-соединение, он не выполняет рукопожатие TLS, так что это вам ни о чем не говорит. Использование SMTPSecure = 'tls' и порта 587 может показать больше обратной связи в отладочных выводах.   -  person Synchro    schedule 01.10.2017
comment
@Synchro Я сделал то, что ты сказал, и теперь получаю Error #2: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed , а затем SMTP Error: Could not connect to SMTP host.. Я начинающий. Что меня смущает, так это то, что моя конфигурация SSL и сертификаты выглядят нормально, но я все еще получаю ошибки. Может быть, я могу обновить свои сертификаты? Спасибо.   -  person slevin    schedule 01.10.2017
comment
Покажите, что содержится в результатах отладки, а не только последнее сообщение об ошибке.   -  person Synchro    schedule 01.10.2017
comment
@Synchro Проверьте обновление в вопросе.   -  person slevin    schedule 01.10.2017
comment
Хорошо, это хотя бы показывает, что вас не перенаправляют куда-то еще. Я предлагаю использовать openssl (как описано в руководстве по устранению неполадок), чтобы проверить, работает ли ваш файл сертификатов CA - Google не будет публиковать недействительный сертификат.   -  person Synchro    schedule 01.10.2017
comment
@Synchro Мне очень жаль, что я не могу помочь ни тебе, ни мне. Я не знаю, как это сделать. Или какая часть руководства на самом деле проверяет сертификаты. echo (extension_loaded('openssl')?'SSL loaded':'SSL not loaded')."\n"; эхо SSL loaded. Запись openssl s_client -starttls smtp -crlf -connect smtp.gmail.com:587 в cmd (windows 10) дает 'openssl' is not recognized as an internal or external command, operable program or batch file. Кстати, я смотрю это руководство https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting.   -  person slevin    schedule 01.10.2017
comment
Ах, я не знаю, как установить openssl на Windows. Найдите это или что-то подобное.   -  person Synchro    schedule 01.10.2017
comment
@Synchro Не знаю, имеет ли это значение, но код работал примерно 50 раз с использованием SMTPSecure = 'ssl' и $mail->Port = 465. Отправьте около 50 писем по электронной почте. А потом просто снова остановился, показывая вышеупомянутые ошибки. Есть ли у сертификатов openssl ограничение на использование? Или это случайное счастливое происшествие?   -  person slevin    schedule 02.10.2017
comment
Нет, ограничения на использование нет, но у Gmail есть ограничение на объем отправки. Не знаю, как это проявляется.   -  person Synchro    schedule 02.10.2017
comment
@Synchro Опять же, я предполагаю, что если бы ошибка была связана с ограничением, Google не разрешил бы соединение. Таким образом, ошибка будет чем-то вроде закрытия соединения, а не сбоя проверки сертификата. Это убивает меня!   -  person slevin    schedule 02.10.2017
comment
@slevin Вы в итоге нашли решение этой проблемы? У меня точно такая же проблема на Windows Server 2016 с PHP 7.0.25; отправил не менее 200 писем в этой конфигурации, и он внезапно перестал работать. Кстати, другие SMTP-серверы (с TLS) работают нормально, просто smtp.gmail.com не работает. Так странно...   -  person Dennis Ameling    schedule 07.11.2017
comment
проверьте мой ответ здесь, это может помочь stackoverflow.com/a/60709451/5068530   -  person vikas etagi    schedule 16.03.2020


Ответы (2)


Было такое же сообщение об ошибке, возможно, у вас такая же проблема:

  • мой сертификат в порядке (я могу без проблем перейти в домен HTTPS)
  • не может выполнить тот же запрос через PHP stream_context_create и stream_socket_client
  • Я хочу проверить SSL-сертификат

Тестирование того же домена через cURL вернуло:

curl: (60) SSL certificate problem: certificate is not yet valid

Оказывается, моя виртуальная машина, на которой я запускал PHP и cURL, имела 11 дней ошибок (11 декабря вместо 22 декабря).

После исправления даты компьютера / виртуальной машины (с помощью ntp, ntpdate-debian и т. д.) проверка сертификата теперь работает нормально как в командной строке cURL, так и в PHP.

person Yvan    schedule 22.12.2017
comment
Да, это было проблемой для меня только что. Эта проблема с Homestead сводит меня с ума каждый день: github.com/laravel/homestead/issues/799 Обычно симптом в другом. У меня раньше не было этой конкретной ошибки, но вы правы, синхронизация часов исправила ее. - person Ryan; 26.05.2019

Я недавно столкнулся с этим на новом сервере Windows IIS. Вызов cURL был направлен в мой собственный домен из пакетного сценария, оба из которых работают на одном сервере.

Я добавил

127.0.0.1  mydomain.com

в файл hosts, и я забыл удалить его, когда изменил общедоступный DNS.

Сервер находится за Cloudflare, поэтому мой cURL получал сертификат происхождения CF, а не настоящий сертификат, обслуживаемый Cloudflare.

Удаление записи hosts устранило проблему.

person IanMcL    schedule 14.01.2019