it-swarm.com.de

SSL-Fehler SSL3_GET_SERVER_CERTIFICATE: Zertifikatprüfung fehlgeschlagen

Nach dem Upgrade auf PHP 5.6 wird eine Fehlermeldung angezeigt, wenn versucht wird, über fsockopen() eine Verbindung zu einem Server herzustellen.

Das Zertifikat auf dem Server (Host) ist selbstsigniert

PHP Warnung: fsockopen (): SSL-Operation mit Code 1 fehlgeschlagen. OpenSSL-Fehlermeldungen: Fehler: 14090086: SSL-Routinen: SSL3_GET_SERVER_CERTIFICATE: Zertifikatprüfung fehlgeschlagen

code

if($fp = fsockopen($Host, $port, $errno, $errstr, 20)){
    $this->request = 'POST '.substr($this->url, strlen($this->Host)).' HTTP/1.1'.$crlf
        .'Host: '.$this->Host.$crlf
        .'Content-Length: '.$content_length.$crlf
        .'Connection: Close'.$crlf.$crlf
        .$body;
    fwrite($fp, $this->request);

    while($line = fgets($fp)){
        if($line !== false){
            $this->response .= $line;
        }
    }

    fclose($fp);
}

Habe versucht

# cd /etc/ssl/certs/
# wget http://curl.haxx.se/ca/cacert.pem

php.ini

openssl.cafile = "/etc/ssl/certs/cacert.pem"

Das Skript funktioniert jedoch immer noch nicht

aktualisieren

Das funktioniert

echo file_get_contents("/etc/ssl/certs/cacert.pem");

update 2

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => true, // You could skip all of the trouble by changing this to false, but it's WAY uncool for security reasons.
        'cafile' => '/etc/ssl/certs/cacert.pem',
        //'CN_match' => 'example.com', // Change this to your certificates Common Name (or just comment this line out if not needed)
        'ciphers' => 'HIGH:!SSLv2:!SSLv3',
        'disable_compression' => true,
    )
);

$context = stream_context_create($contextOptions);

$fp = stream_socket_client("{$Host}:{$port}", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $context);

error

PHP Warnung: stream_socket_client (): SSL-Operation mit Code 1 fehlgeschlagen. OpenSSL-Fehlermeldungen: Fehler: 14090086: SSL-Routinen: SSL3_GET_SERVER_CERTIFICATE: Zertifikatprüfung fehlgeschlagen

39
clarkk

Die heruntergeladene Datei (_ (( http://curl.haxx.se/ca/cacert.pem ) ist ein Bündel der Stammzertifikate der wichtigsten vertrauenswürdigen Zertifizierungsstellen. Sie sagten, dass der entfernte Host über ein selbstsigniertes SSL-Zertifikat verfügt und kein vertrauenswürdiges Zertifikat verwendet hat. Die Einstellung openssl.cafile muss auf das CA-Zertifikat verweisen, das zum Signieren des SSL-Zertifikats auf dem Remote-Host verwendet wurde. PHP 5.6 wurde gegenüber früheren Versionen von PHP verbessert, um Peer-Zertifikate und Hostnamen standardmäßig zu überprüfen ( http://php.net/manual/de/migration56.openssl.php )

Sie müssen das CA-Zertifikat suchen, das auf dem Server generiert wurde, der das SSL-Zertifikat signiert hat, und es auf diesen Server kopieren. Die einzige andere Option ist das Deaktivieren der Überprüfung des Peers, was jedoch die SSL-Sicherheit beeinträchtigt. Wenn Sie die Überprüfung deaktivieren möchten, versuchen Sie dieses Array mit dem Code aus meiner vorherigen Antwort:

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false
    )
);

Wenn Sie selbstsignierte Zertifikate verwenden, müssen Sie in jedem Fall das Zertifizierungsstellenzertifikat hinzufügen, das zum Signieren des SSL-Zertifikats des Remote-Hosts dem vertrauenswürdigen Speicher auf dem Server verwendet wurde, den Sie über OR verwenden Streamkontexte, um dieses Zertifikat für jede einzelne Anforderung zu verwenden. Das Hinzufügen zu den vertrauenswürdigen Zertifikaten ist die einfachste Lösung. Fügen Sie einfach den Inhalt des CA-Zertifikats des Remote-Hosts am Ende der heruntergeladenen Datei cacert.pem hinzu.

Bisherige:

fsockopen unterstützt keine Stream-Kontexte, verwenden Sie stattdessen stream_socket_client. Es gibt eine Ressource zurück, die mit allen Befehlen von fsockopen-Ressourcen verwendet werden kann. 

Dies sollte ein Tropfen Ersatz für das in Ihrer Frage enthaltene Snippet sein:

<?php

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => true, // You could skip all of the trouble by changing this to false, but it's WAY uncool for security reasons.
        'cafile' => '/etc/ssl/certs/cacert.pem',
        'CN_match' => 'example.com', // Change this to your certificates Common Name (or just comment this line out if not needed)
        'ciphers' => 'HIGH:!SSLv2:!SSLv3',
        'disable_compression' => true,
    )
);

$context = stream_context_create($contextOptions);

$fp = stream_socket_client("tcp://{$Host}:{$port}", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $context);

if (!$fp) {

    echo "$errstr ({$errno})<br />\n";

}else{

    $this->request = 'POST '.substr($this->url, strlen($this->Host)).' HTTP/1.1'.$crlf
        .'Host: '.$this->Host.$crlf
        .'Content-Length: '.$content_length.$crlf
        .'Connection: Close'.$crlf.$crlf
        .$body;

    fwrite($fp, $this->request);

    while (!feof($fp)) {
        $this->response .= fgets($fp);
    }

    fclose($fp);

}
29
aecend

Das Problem ist in der neuen PHP Version in macOS Sierra

Bitte hinzufügen 

stream_context_set_option($ctx, 'ssl', 'verify_peer', false);

Bei der Arbeit mit Ubuntu 16.04 hatte ich mit Docker ein ähnliches Problem. In meinem Fall war das ein Problem mit Composer, aber die Fehlermeldung (und damit das Problem) war die gleiche.

Wegen des minimalistischen Docker-orientierten Basisimage hatte ich das ca-certificates-Paket und das einfache apt-get install ca-certificates vermisst.

Hinzufügen 

$mail->SMTPOptions = array(
'ssl' => array(
    'verify_peer' => false,
    'verify_peer_name' => false,
    'allow_self_signed' => true
));

vor

mail->send()

und ersetzen

require "mailer/class.phpmailer.php";

mit

require "mailer/PHPMailerAutoload.php";
3
Himanshu Sharma

Sie erwähnen, dass das Zertifikat (von Ihnen) selbst signiert ist? Dann haben Sie zwei Möglichkeiten:

  • fügen Sie das Zertifikat Ihrem Trust Store hinzu (das Abrufen von cacert.pem von der cURL-Website führt zu nichts, da es selbstsigniert ist)
  • vergewissern Sie sich nicht, das Zertifikat zu überprüfen: Sie vertrauen sich selbst, nicht wahr?

Hier eine Liste der SSL-Kontextoptionen in PHP: https://secure.php.net/manual/de/context.ssl.php

Legen Sie allow_self_signed fest, wenn Sie Ihr Zertifikat in Ihren Trust Store importieren, oder setzen Sie verify_peer auf false, um die Überprüfung zu überspringen.

Der Grund, warum wir einem bestimmten Zertifikat vertrauen, liegt darin, dass wir seinem Emittenten vertrauen. Da Ihr Zertifikat selbstsigniert ist, vertraut kein Client dem Zertifikat, da der Unterzeichner (Sie) nicht vertrauenswürdig ist. Wenn Sie beim Signieren des Zertifikats eine eigene Zertifizierungsstelle erstellt haben, können Sie die Zertifizierungsstelle Ihrem Trust Store hinzufügen. Wenn Ihr Zertifikat keine Zertifizierungsstelle enthält, können Sie nicht erwarten, dass sich jemand mit Ihrem Server verbindet.

0
DavidS

In meinem Fall war ich auf CentOS 7 und meine PHP-Installation zeigte auf ein Zertifikat, das durch update-ca-trust generiert wurde. Der Symlink war /etc/pki/tls/cert.pem und zeigte auf /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem. Dies war nur ein Testserver, und ich wollte, dass mein selbst signiertes Zertifikat ordnungsgemäß funktioniert. Also in meinem Fall ...

# My root ca-trust folder was here. I coped the .crt file to this location
# and renamed it to a .pem
/etc/pki/ca-trust/source/anchors/self-signed-cert.pem

# Then run this command and it will regenerate the certs for you and
# include your self signed cert file.
update-ca-trust

Dann begannen einige meiner API-Aufrufe zu funktionieren, da mein Zertifikat nun vertrauenswürdig war. Auch wenn Ihr ca-trust durch yum oder etwas aktualisiert wird, werden Ihre Stammzertifikate neu erstellt und Ihr selbstsigniertes Zertifikat bleibt erhalten. Führen Sie man update-ca-trust aus, um weitere Informationen darüber zu erhalten, was zu tun ist und wie. :)

0
n0nag0n

Wenn Sie macOS sierra verwenden, gibt es ein Update in der Version PHP. Sie müssen die Datei Entrust.net Certificate Authority (2048) zum Code PHP hinzufügen. mehr Info Check akzeptierte Antwort hier Push-Benachrichtigung in PHP mit PEM-Datei

0
Im Batman

Stellen Sie zunächst sicher, dass die Antivirensoftware SSL2 nicht blockiert.
Weil ich ein Problem lange Zeit nicht lösen konnte und nur das Deaktivieren des Virenschutzes half

0