Signatur
Beschreibung
stream_socket_enable_crypto() aktiviert oder deaktiviert die kryptografische Verschlüsselung auf einem Stream-Socket, der zuvor mit stream_socket_client() oder stream_socket_server() erstellt wurde. Die Funktion ist besonders nützlich, wenn eine Verbindung zunächst unverschlüsselt aufgebaut und später auf TLS/SSL hochgestuft werden soll – ein Vorgang, der als STARTTLS bekannt ist (z. B. bei SMTP, IMAP oder FTP).
Der Parameter $crypto_method legt das gewünschte Protokoll fest (z. B. STREAM_CRYPTO_METHOD_TLS_CLIENT). Wird er weggelassen, muss die Verschlüsselungsmethode zuvor über den Stream-Kontext mit der Option crypto_method festgelegt worden sein. Der optionale Parameter $session_stream erlaubt es, Sitzungsdaten eines anderen Streams wiederzuverwenden, um den TLS-Handshake zu beschleunigen.
Die Funktion gibt im nicht-blockierenden Modus 0 zurück, wenn der Handshake noch nicht abgeschlossen ist – in diesem Fall muss sie erneut aufgerufen werden. Im blockierenden Modus liefert sie true bei Erfolg und false bei einem Fehler.
Typische Einsatzszenarien sind selbst implementierte Mail-Clients, FTP-Bibliotheken oder andere Protokolle, bei denen der Wechsel von Klartext zu Verschlüsselung mitten in einer bestehenden Verbindung erfolgt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $stream Pflicht | resource | Ein gültiger Stream-Socket, der bereits verbunden ist (erstellt z. B. mit stream_socket_client() oder stream_socket_server()). |
|
| $enable Pflicht | bool | true, um Verschlüsselung zu aktivieren; false, um sie zu deaktivieren. |
|
| $crypto_method | int|null | null | Die gewünschte Verschlüsselungsmethode. Mögliche Werte sind Konstanten wie STREAM_CRYPTO_METHOD_TLS_CLIENT, STREAM_CRYPTO_METHOD_TLS_SERVER, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT usw. Wird null übergeben, muss die Methode im Stream-Kontext definiert sein. |
| $session_stream | resource|null | null | Ein optionaler Stream, dessen TLS-Sitzungsdaten wiederverwendet werden sollen, um den Handshake zu beschleunigen (Session Resumption). |
Rückgabewert
true zurück, wenn Verschlüsselung erfolgreich aktiviert/deaktiviert wurde, false bei einem Fehler. Im nicht-blockierenden Modus wird 0 zurückgegeben, wenn der TLS-Handshake noch nicht abgeschlossen ist und die Funktion erneut aufgerufen werden muss.Beispiele
STARTTLS mit einem SMTP-Server
<?php
$server = 'smtp.example.com';
$port = 587;
// Unverschlüsselte Verbindung herstellen
$socket = stream_socket_client(
"tcp://{$server}:{$port}",
$errno,
$errstr,
30
);
if (!$socket) {
die("Verbindungsfehler: $errstr ($errno)\n");
}
// Server-Begrüßung lesen
echo fgets($socket, 1024);
// EHLO senden
fwrite($socket, "EHLO localhost\r\n");
while ($line = fgets($socket, 1024)) {
echo $line;
if (substr($line, 3, 1) === ' ') break; // Letzte Antwortzeile
}
// STARTTLS anfordern
fwrite($socket, "STARTTLS\r\n");
echo fgets($socket, 1024);
// TLS-Handshake durchführen
$result = stream_socket_enable_crypto(
$socket,
true,
STREAM_CRYPTO_METHOD_TLS_CLIENT
);
if ($result === true) {
echo "TLS erfolgreich aktiviert.\n";
// Ab hier verschlüsselt kommunizieren ...
} else {
echo "TLS-Handshake fehlgeschlagen.\n";
}
fclose($socket);
Verschlüsselung auf einem nicht-blockierenden Socket aktivieren
<?php
$context = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
]
]);
$socket = stream_socket_client(
'tcp://example.com:443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$context
);
if (!$socket) {
die("Verbindungsfehler: $errstr ($errno)\n");
}
// Nicht-blockierenden Modus aktivieren
stream_set_blocking($socket, false);
// Handshake-Schleife für nicht-blockierenden Modus
do {
$result = stream_socket_enable_crypto(
$socket,
true,
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
);
if ($result === false) {
die("TLS-Fehler aufgetreten.\n");
}
// 0 bedeutet: Handshake noch nicht abgeschlossen
} while ($result === 0);
echo "TLS-Verbindung hergestellt.\n";
// HTTPS-Anfrage senden
fwrite($socket, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
stream_set_blocking($socket, true);
echo stream_get_contents($socket);
fclose($socket);
// Wichtig · Fallstricke
Sicherheitshinweis: Deaktivieren Sie niemals die Peer-Verifizierung (verify_peer und verify_peer_name) in Produktionsumgebungen, da dies die Verbindung anfällig für Man-in-the-Middle-Angriffe macht.
Protokollwahl: Bevorzugen Sie STREAM_CRYPTO_METHOD_TLS_CLIENT (welches automatisch TLS 1.0–1.3 umfasst, je nach PHP- und OpenSSL-Version) gegenüber veralteten Konstanten wie STREAM_CRYPTO_METHOD_SSLv3_CLIENT, da SSLv2 und SSLv3 als unsicher gelten und in modernen PHP-/OpenSSL-Versionen nicht mehr unterstützt werden.
Reihenfolge beachten: Die Funktion darf erst aufgerufen werden, wenn die Verbindung vollständig hergestellt ist. Bei STARTTLS-Protokollen muss zuerst der protokollspezifische Handshake (z. B. STARTTLS-Kommando bei SMTP) abgeschlossen sein, bevor TLS aktiviert wird.
Wenn $enable auf false gesetzt wird, wird Verschlüsselung deaktiviert – dies ist in den meisten Protokollen nicht vorgesehen und kann zu unerwarteten Sicherheitsproblemen führen.