在PHP 中,利用socket_accept()接受客戶端連接後,結合OpenSSL 擴展實現TLS 加密傳輸,是提升網絡通信安全性的常用方法。本文將介紹如何用原生socket 接口與OpenSSL 擴展配合,實現基於TLS 的加密傳輸。
確保PHP 支持OpenSSL 擴展<br> 通過phpinfo()或命令行php -m查看是否已啟用openssl模塊
準備證書和私鑰<br> 可以使用OpenSSL 命令生成自簽名證書,示例
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
創建socket 服務器<br> 使用socket_create()和相關函數搭建基本的TCP 服務器
下面的示例演示如何使用socket_accept()接受客戶端連接後,通過OpenSSL 擴展進行TLS 握手和加密通信。
<?php
$host = '0.0.0.0';
$port = 8443;
// 創建 TCP socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $host, $port);
socket_listen($sock);
echo "服務器啟動,監聽 {$host}:{$port}\n";
// 載入證書和私鑰路徑
$certFile = '/path/to/server.crt';
$keyFile = '/path/to/server.key';
// 等待客戶端連接
while (true) {
$clientSock = socket_accept($sock);
if ($clientSock === false) {
echo "接受連接失敗\n";
continue;
}
// 創建基于 socket 的 stream 資源
$clientStream = socket_export_stream($clientSock);
// 創建 SSL 上下文
$context = stream_context_create([
'ssl' => [
'local_cert' => $certFile,
'local_pk' => $keyFile,
'allow_self_signed' => true,
'verify_peer' => false,
]
]);
// 將普通的 TCP 連接升級為 TLS 加密連接
$sslStream = stream_socket_enable_crypto($clientStream, true, STREAM_CRYPTO_METHOD_TLS_SERVER);
if (!$sslStream) {
echo "TLS 握手失敗\n";
fclose($clientStream);
socket_close($clientSock);
continue;
}
// 讀取客戶端數據
$data = fread($clientStream, 8192);
echo "收到數據:$data\n";
// 發送響應
fwrite($clientStream, "Hello from m66.net TLS server!\n");
// 關閉連接
fclose($clientStream);
socket_close($clientSock);
}
socket_close($sock);
socket_export_stream()
該函數將socket 資源轉換為PHP 的stream 資源,這樣才可以用stream_socket_enable_crypto()進行TLS 升級。
stream_socket_enable_crypto()
負責TLS 握手和加密啟動,第三個參數選擇服務端模式( STREAM_CRYPTO_METHOD_TLS_SERVER ),開啟加密。
證書配置
stream_context_create()中傳入證書和私鑰路徑。示例中allow_self_signed和verify_peer設置適合測試環境,正式環境應開啟驗證。
數據傳輸<br> 之後的數據讀寫均通過加密後的stream 進行,自動完成加密和解密
通過socket_accept()和OpenSSL 擴展配合,PHP 可以靈活實現TLS 加密傳輸,保證數據安全。關鍵在於將socket 資源轉成stream,利用stream_socket_enable_crypto()進行加密升級,結合有效的證書管理,即可輕鬆構建安全的加密通信服務。