PHP Conference Japan 2024

stream_socket_enable_crypto

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

stream_socket_enable_crypto在已連線的通訊端上開啟/關閉加密

說明

stream_socket_enable_crypto(
    資源 $stream,
    布林值 $enable,
    ?整數 $crypto_method = null,
    ?資源 $session_stream = null
): 整數 (int)|布林值 (bool)

啟用或停用串流上的加密。

一旦加密設定建立完成,就可以透過在 enable 參數中傳遞 truefalse 來動態開啟和關閉加密功能。

回傳值

成功時回傳 true,協商失敗時回傳 false,如果資料不足且您應該重試則回傳 0(僅適用於非阻塞式通訊端)。

更新日誌

版本 說明
8.0.0 session_stream 現在可以為 null。

範例

範例 #1 stream_socket_enable_crypto() 範例

<?php
$fp
= stream_socket_client("tcp://myproto.example.com:31337", $errno, $errstr, 30);
if (!
$fp) {
die(
"無法連線: $errstr ($errno)");
}

/* 登入階段開啟加密 */
stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
fwrite($fp, "USER god\r\n");
fwrite($fp, "PASS secret\r\n");

/* 其餘部分關閉加密 */
stream_socket_enable_crypto($fp, false);

while (
$motd = fgets($fp)) {
echo
$motd;
}

fclose($fp);
?>

上述範例會輸出類似以下的內容


新增筆記

使用者貢獻的筆記 4 則筆記

tigger (AT) tiggerswelt d0t net
17 年前
如上所述

如果 socket 處於非阻塞模式,stream_socket_enable_crypto 很可能會失敗/返回零。

您可以等待幾秒鐘,直到所有必要的數據到達,或者暫時切換到阻塞模式

<?PHP

stream_set_blocking
($fd, true);
stream_socket_enable_crypto ($fd, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
stream_set_blocking ($fd, false);

?>

這對我來說非常有效 ;-)
匿名
2 年前
如果您需要在處理完未加密的流量後將串流從未加密更改為加密,則在讀取未加密的流量時,請使用 stream-socket-recvfrom 函數進行讀取,而不是 fread。 使用 fread 會導致初始 CLIENT HELLO 訊息的某些緩衝區被讀入其緩衝區,從而在某些情況下導致 SSL 握手失敗。
play dot it at play-it dot net
1 年前
關於 `crypto_method` 差異的資訊

有 `STREAM_CRYPTO_METHOD_*_CLIENT` 和 `STREAM_CRYPTO_METHOD_*_SERVER`

`STREAM_CRYPTO_METHOD_*_CLIENT` 用於客戶端,例如
```php
<?php
$client
= stream_socket_client("tcp://example.com:443", $errno, $errstr);
stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);

//...
?>
```

這段程式碼進行 TLS 握手,`stream_socket_enable_crypto` 會發送 `Client HELLO`

`STREAM_CRYPTO_METHOD_*_SERVER` 用於伺服器端,例如
<?php
$server
= stream_socket_server("tcp://example.com:443", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
stream_context_set_option($server, ["ssl" => [
"local_cert" => __DIR__."/https.crt",
"local_pk" => __DIR__."/https.key",
]]);

//...

$client = stream_socket_accept($server);
stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_SERVER);

//...
?>

這段程式碼會執行 TLS 握手,並且在客戶端發送「Client HELLO」之後,`stream_socket_enable_crypto` 會發送「Server HELLO」。

因此,在接受客戶端連線後,使用 `STREAM_CRYPTO_METHOD_*_CLIENT` 來請求數據,使用 `STREAM_CRYPTO_METHOD_*_SERVER` 來提供數據。
Zero
1 年前
自 PHP 7.2 起,TLS 等同於 TLS_ANY,因此 STREAM_CRYPTO_METHOD_TLS_CLIENT 表示任何 TLS 版本。
To Top