Signatur
Beschreibung
PHP ermöglicht es, SSL/TLS-Verbindungen über Stream-Kontexte zu konfigurieren. Die SSL-Kontextoptionen werden als assoziatives Array unter dem Wrapper-Schlüssel 'ssl' an stream_context_create() übergeben und steuern u. a. Zertifikate, Verschlüsselung, Peer-Verifizierung und Timeouts.
Typische Einsatzbereiche sind HTTPS-Anfragen mit file_get_contents(), fopen() oder Sockets, wenn man eigene CA-Bundles, Client-Zertifikate oder Cipher-Suiten festlegen möchte. Besonders im API-Kontext oder bei internen Diensten mit selbstsignierten Zertifikaten sind diese Optionen unentbehrlich.
Die wichtigsten Optionen umfassen: verify_peer und verify_peer_name (Peer-Verifikation), cafile/capath (CA-Bundle/-Verzeichnis), local_cert/local_pk (Client-Zertifikat/Schlüssel), ciphers (erlaubte Cipher-Suiten), crypto_method (TLS-Version), peer_name (erwarteter Hostname), allow_self_signed, passphrase und SNI_enabled.
Ab PHP 5.6 ist die Peer-Verifizierung standardmäßig aktiviert und strenger konfiguriert. Es empfiehlt sich dringend, verify_peer und verify_peer_name niemals auf false zu setzen, außer in kontrollierten Entwicklungsumgebungen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $peer_name | string | Erwarteter Hostname des entfernten Servers. Wird für SNI und Zertifikatsprüfung verwendet. | |
| $verify_peer | bool | true | Gibt an, ob das SSL-Zertifikat der Gegenseite verifiziert werden soll. Seit PHP 5.6 standardmäßig true. |
| $verify_peer_name | bool | true | Gibt an, ob der Hostname im Zertifikat gegen peer_name bzw. den verbundenen Host geprüft wird. |
| $allow_self_signed | bool | false | Erlaubt selbstsignierte Zertifikate, wenn verify_peer aktiv ist. |
| $cafile | string | Pfad zu einer CA-Bundle-Datei im PEM-Format, gegen die das Peer-Zertifikat geprüft wird. | |
| $capath | string | Verzeichnis mit vertrauenswürdigen CA-Zertifikaten im PEM-Format. | |
| $local_cert | string | Pfad zur lokalen Zertifikatsdatei (PEM) für die Client-Authentifizierung. | |
| $local_pk | string | Pfad zum privaten Schlüssel (PEM) des Client-Zertifikats. | |
| $passphrase | string | Passphrase für das verschlüsselte Client-Zertifikat oder den privaten Schlüssel. | |
| $ciphers | string | DEFAULT | Kommagetrennte Liste erlaubter Cipher-Suiten im OpenSSL-Format, z. B. 'HIGH:!aNULL:!MD5'. |
| $capture_peer_cert | bool | false | Speichert das Peer-Zertifikat im Kontext-Parameter peer_certificate, abrufbar via stream_context_get_params(). |
| $capture_peer_cert_chain | bool | false | Speichert die gesamte Zertifikatskette der Gegenseite im Kontext. |
| $SNI_enabled | bool | true | Aktiviert Server Name Indication (SNI), damit virtuelle SSL-Hosts korrekt unterschieden werden. |
| $disable_compression | bool | true | Deaktiviert TLS-Komprimierung, um CRIME-Angriffe zu verhindern. |
| $peer_fingerprint | string|array | SHA-1- oder SHA-256-Fingerabdruck (hex) des erwarteten Peer-Zertifikats oder ein assoziatives Array ['sha256' => '...'] für Certificate Pinning. |
|
| $crypto_method | int | STREAM_CRYPTO_METHOD_TLS_CLIENT | Legt die erlaubten TLS-Protokollversionen fest, z. B. STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT. |
Rückgabewert
Beispiele
HTTPS-Anfrage mit eigenem CA-Bundle und TLSv1.2
<?php
$context = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/ca-bundle.crt',
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
'ciphers' => 'HIGH:!aNULL:!MD5',
'disable_compression' => true,
],
]);
$response = file_get_contents('https://example.com/api/data', false, $context);
if ($response === false) {
echo 'Verbindung fehlgeschlagen.';
} else {
echo 'Antwortlänge: ' . strlen($response) . ' Bytes';
}
Client-Zertifikat-Authentifizierung (mTLS)
<?php
$context = stream_context_create([
'ssl' => [
'local_cert' => '/pfad/zum/client-cert.pem',
'local_pk' => '/pfad/zum/client-key.pem',
'passphrase' => 'geheimesPasswort',
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/pfad/zur/server-ca.pem',
],
]);
$fp = stream_socket_client(
'ssl://api.intern.example.com:443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$context
);
if (!$fp) {
echo "Fehler $errno: $errstr";
} else {
fwrite($fp, "GET /status HTTP/1.0\r\nHost: api.intern.example.com\r\n\r\n");
echo fread($fp, 4096);
fclose($fp);
}
Certificate Pinning via peer_fingerprint
<?php
// SHA-256-Fingerabdruck des erwarteten Zertifikats (hex)
$expectedFingerprint = 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99';
$context = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'peer_fingerprint' => ['sha256' => $expectedFingerprint],
],
]);
$data = file_get_contents('https://secure.example.com/', false, $context);
echo $data !== false ? 'Zertifikat verifiziert.' : 'Zertifikat stimmt nicht überein!';
// Wichtig · Fallstricke
Sicherheitswarnung: Setze verify_peer oder verify_peer_name niemals auf false in Produktionssystemen — dadurch werden Man-in-the-Middle-Angriffe ermöglicht. Auch allow_self_signed => true sollte nur in abgeschlossenen internen Umgebungen verwendet werden.
Seit PHP 5.6 sind die Standardwerte für verify_peer und verify_peer_name auf true gesetzt. Älterer Code, der diese Optionen nicht setzt, kann dadurch unter PHP 5.6+ brechen, wenn der Server kein vertrauenswürdiges Zertifikat liefert.
Die Option crypto_method sollte auf mindestens STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT gesetzt werden. TLS 1.0 und 1.1 gelten als veraltet (RFC 8996). Ab PHP 8.1 sind TLS 1.0 und 1.1 standardmäßig deaktiviert.
Der Wrapper-Schlüssel für den Kontext lautet 'ssl' — auch für tls://-Verbindungen wird intern derselbe Schlüssel verwendet.