Wie erzwinge ich eine bestimmte TLS-Version in einem PHP-Stream-Kontext für den ssl://-Transport?

Lesezeit: 7 Minuten

Wie kann ich TLSv1.0 in einem PHP-Stream-Kontext erzwingen, wenn ich versuche, auf eine https URL?

Ich suche sowas in der Richtung:

$context = stream_context_create(
  array(
    'ssl' => array(
      'protocol_version' => 'tls1',
    ),
  ));
file_get_contents('https://example.com/test', false, $context);

Hintergrund

Eigentlich stehe ich vor ein Problem in Ubuntu 12.04 bei der Arbeit mit PHP’s SoapClient. Leider unterstützt der Server, mit dem ich eine Verbindung herstellen möchte, nur SSLv3.0/TLSv1.0 und schlägt bei der standardmäßigen TLSv1.1-Aushandlung fehl. Daher möchte ich explizit das Protokoll der einstellen ssl:// Transport zu TLSv1.0.

Wie erzwinge ich eine bestimmte TLS Version in einem PHP Stream Kontext fur
phil-lavin

PHP 5.6+ Benutzer

Dies ist eine neue Funktion, die auf der dokumentiert ist PHP 5.6 OpenSSL-Änderungsseite.

Zum Zeitpunkt des Schreibens dieses Artikels befindet sich PHP5.6 in Beta1 und ist daher nicht besonders nützlich. Menschen der Zukunft – Glück gehabt!

Die Zukunft liegt vor uns. PHP 5.6 ist eine Sache und seine Verwendung sollte gefördert werden. Beachten Sie, dass einige ziemlich weit verbreitete Dinge wie mysql_*-Funktionen veraltet sind, also sollten Sie beim Upgrade vorsichtig sein.

Jeder andere

@toubsen hat Recht mit seiner Antwort – das ist nicht direkt möglich. Um auf seine vorgeschlagenen Problemumgehungen näher einzugehen … bei der Umgehung eines Problems, bei dem der API-Server eines Anbieters TLSv1.2 nicht korrekt auf sein unterstütztes TLSv1.0 aushandelte, schien das Senden einer kleinen Teilmenge von Chiffren zu ermöglichen, dass die Aushandlung korrekt abgeschlossen wurde. Stream-Kontextcode ist:

$context = stream_context_create(
    [
        'ssl' => [
            'ciphers' => 'DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:KRB5-DES-CBC3-MD5:KRB5-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DES-CBC3-MD5:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC2-CBC-MD5:KRB5-RC4-MD5:KRB5-RC4-SHA:RC4-SHA:RC4-MD5:RC4-MD5:KRB5-DES-CBC-MD5:KRB5-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:DES-CBC-MD5:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-KRB5-RC4-MD5:EXP-KRB5-RC4-SHA:EXP-RC4-MD5:EXP-RC4-MD5',
        ],
    ]
);

SOAP-Benutzer

Der SOAP-Client von PHP verwendet weder curl noch scheint er den standardmäßigen Kontextsatz mit zu verwenden stream_context_set_default. Daher muss der erstellte Kontext als solcher im 2. Parameter an den SOAPClient-Konstruktor übergeben werden:

$soap_client = new SOAPClient('http://webservices.site.com/wsdlfile.wsdl', array('stream_context' => $context));

Warum diese Chiffren?

Ausführen des Befehls openssl ciphers auf dem Server gibt Ihnen eine Liste der unterstützten Chiffren im obigen Format. Laufen openssl ciphers -v teilt Ihnen diejenigen mit, die TLSv1.2-spezifisch sind. Die obige Liste wurde aus allen Nicht-TLSv1.2-Chiffren zusammengestellt, die von OpenSSL gemeldet wurden.

openssl ciphers -v | grep -v 'TLSv1.2' | cut -d ' ' -f 1 | tr "\n" ':'

  • Obwohl ich dies nicht mehr testen kann (siehe meinen Kommentar zu Toubsens Antwort), scheint dies die richtige Antwort zu sein. Ich nehme an, sie hätten das nicht hinzugefügt crypto_method SSL-Kontextoption für PHP 5.6, wenn es in früheren PHP-Versionen eine andere Lösung gegeben hätte. Wir werden also wohl mit den beschriebenen Workarounds leben müssen, bis PHP 5.6 produktiv eingesetzt werden kann. Danke!

    – Chriki

    19. April 2014 um 12:42 Uhr

  • Verwenden 'ciphers' in PHP 5.4 scheint die Chiffren einzuschränken, daher sollte die Auswahl nur von Chiffren, die für TLSv1.2 definiert sind, auch in 5.4 funktionieren.

    – Christoph Schultz

    2. Februar 2017 um 22:12 Uhr

  • Diese Lösung funktionierte in PHP 7.0 und openssl 1.0.2k für einen Server, der TLS1.2 nicht aushandeln und nicht auf TLS1.0 herunterverhandeln würde. VIEL zu viel Zeit damit verbracht, dies zum Laufen zu bringen.

    – Todd Hammer

    29. August 2018 um 17:07 Uhr

Wie erzwinge ich eine bestimmte TLS Version in einem PHP Stream Kontext fur
Robert McMahan

Falls jemand wissen möchte, wie man TLSv1.0 “deaktiviert”, wenn er eine SOAP-Anfrage stellt …

$parameters = array(
    'trace' => true,
    'exceptions' => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => stream_context_create(array(
        'ssl' => array(
            'ciphers' => 'DEFAULT:!TLSv1.0:!SSLv3'
        ),
    )),
    'connection_timeout' => 15
);

$client = new SoapClient(YOUR_WSDL_URL_HERE, $parameters);

Der Schlüsselteil hier ist dieser Stream-Kontext Chiffren Linie. Dies besagt, dass Sie die Standardchiffren verwenden, aber TLSv1.0-Chiffren ausschließen (das 1.0-Paket enthält auch TLSv1.1-Chiffren). Das : ist das Chiffrierpakettrennzeichen (was zwischen Paketen steht) und das ! hier ist, ihm zu sagen, dass es dieses Paket ausschließen soll (es ist ein harter Ausschluss, wenn es also später in der Liste auftaucht, wird es immer noch ausgeschlossen). Weicher Ausschluss ist – Zeichen und Hinzufügen am Ende der Liste ist + Zeichen. Um es in der Reihenfolge hinzuzufügen, fügen Sie es einfach ohne irgendetwas davor hinzu.

Chiffreinformationen hier: https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-LIST-FORMAT

Edit: Aus welchem ​​Grund auch immer

'ssl_method' => SOAP_SSL_METHOD_TLS,

Ein Teil der Optionen bereitete mir wirklich Kopfschmerzen und würde in bestimmten Kontexten keine Verbindung herstellen. Nach unzähligen Fehlerbehebungen und dem Herumspielen mit Optionen wurde mir schließlich klar, dass das Entfernen dieser Einstellung und das automatische Festlegen dieser Einstellung das Problem anscheinend behoben hat.

  • Ich konnte keine Verbindung von PHP 5.5 zu einem Server herstellen, der TLS1.1 nicht mehr akzeptiert. Leider ist die Verwendung von crypto_method keine Option, da die Konstante STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT neu in PHP 5.6 ist. Ihre Bearbeitung zum Entfernen von „ssl_method“ hat das Problem gelöst.

    – David

    14. Dezember 2017 um 11:39 Uhr

  • @David, freut mich zu hören! Ich habe ewig gebraucht, um herauszufinden, was zum Teufel los war. Sie haben Recht mit dieser Konstante. Ich hatte das gleiche Problem und konnte es auch nicht verwenden, also musste ich nach Alternativen suchen. DANN bin ich im Streamkontext gelandet. Das funktionierte einigermaßen und dann wurde mir klar, dass ich die alte Konstante für die SSL-Methode entfernen musste, weil sie sie zurück auf TLS 1.1 zwang und die Dinge abspritzte.

    – Robert McMahan

    29. Dezember 2017 um 17:20 Uhr

  • @David Ihr Vorschlag war nützlich, aber in meinem Fall mit PHP 5.5 kommentieren Sie einfach die ssl_method aus, um das Problem zu lösen.

    – Adriano Rosa

    31. Juli 2018 um 16:15 Uhr

  • Beachten Sie, dass Sie dazu auch eine Version der OpenSSL-Bibliotheken benötigen, die die TLS-Version unterstützen, die Sie verwenden möchten. In meinem Fall benötigte ich beim Versuch, die Verwendung von TLSv1.2 zu erzwingen, OpenSSL 1.0.1 und höher. php -r 'echo OPENSSL_VERSION_TEXT . "\n";' zeigte “OpenSSL 0.9.8zc 19 Mar 2015”, also hatte ich Pech und bekam “stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version” . Durch das Upgrade auf OpenSSL 1.0.2 wurde eine erfolgreiche Verbindung mit TLSv1.2 hergestellt.

    – Dewi Morgan

    18. Oktober 2021 um 14:33 Uhr

1647134049 899 Wie erzwinge ich eine bestimmte TLS Version in einem PHP Stream Kontext fur
Toubsen

Basisinformationen

Das Feld protocol_version gilt nur für den HTTP-Kontext (HTTP 1.0 vs. 1.1), wirkt sich aber nicht auf den SSL-Kontext aus.

Die folgende Handbuchseite listet alle Stream-Kontextoptionen für PHP auf:
Kontextoptionen und Parameter

Für alle SSL-basierten Stream-Wrapper sind nur die folgenden Optionen verfügbar:
SSL-Kontextoptionen

Mögliche Lösungen / Problemumgehungen

Erster Rat: Lassen Sie den Serveradministrator seinen Server reparieren, anstatt dies in Ihrem Client zu umgehen 😉

Vielleicht kannst du es mit dem zum Laufen bringen ciphers Möglichkeit für SSL-Streams, um nur eine exakte zu übergeben TLSv1.0-Verschlüsselungssammlung (das ist einzigartig für TLSv1.0) in der Liste, die Ihr Zielserver unterstützt.

Eine Umstellung der Implementierung auf die Verwendung von cURL wird hier höchstwahrscheinlich auch nicht helfen, wie gem einen Eintrag in ihrer Mailinglistegibt es keine Option, eine bestimmte TLS-Version zu erzwingen – der Client führt bei Bedarf automatisch ein Downgrade durch.

tl;dr

Mir ist derzeit keine Möglichkeit bekannt, TLSv1.0 explizit für SSL-Verbindungen von PHP zu erzwingen.

  • Danke für deine Antwort. Leider – oder eigentlich zum Glück – wurde das Problem, das ich hatte, schließlich auf der Serverseite gelöst. Zuerst hatte ich keine Chance die Admins zu überzeugen, aber offensichtlich haben sie ihren Server inzwischen aktualisiert. Dennoch können diese Hintergrundinformationen und Lösungsvorschläge für andere hilfreich sein, die mit ähnlichen Problemen konfrontiert sind. Zu deinem Vorschlag mit der ciphers Option: Ich glaube, das hatte ich damals erfolglos versucht; aber ich erinnere mich nicht richtig. Jetzt kann ich es nicht mehr testen …

    – Chriki

    19. November 2013 um 15:03 Uhr

Ich kann bestätigen, dass die oben akzeptierte Antwort nicht für die Kombination von Ubuntu 12.04 und PHP 5.4.33 funktioniert. Außerdem habe ich herausgefunden, dass ich das Zertifikat manuell angeben muss, wenn ich versuche, mit openssl und curl auf https-Endpunkte zuzugreifen. Am Ende verwendete ich RHEL 7 und PHP 5.5, um eine solide Lösung zu erreichen, als ich die Integration für eine Unternehmensanwendung entwickelte. Nichts gegen Ubuntu, aber in meinem speziellen Fall hat es nicht funktioniert.

995530cookie-checkWie erzwinge ich eine bestimmte TLS-Version in einem PHP-Stream-Kontext für den ssl://-Transport?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy