當前位置: 首頁> 最新文章列表> socket_accept() + TLS 實現數據加密傳輸(結合OpenSSL 擴展)

socket_accept() + TLS 實現數據加密傳輸(結合OpenSSL 擴展)

M66 2025-06-01

在PHP 中,利用socket_accept()接受客戶端連接後,結合OpenSSL 擴展實現TLS 加密傳輸,是提升網絡通信安全性的常用方法。本文將介紹如何用原生socket 接口與OpenSSL 擴展配合,實現基於TLS 的加密傳輸。

一、準備工作

  1. 確保PHP 支持OpenSSL 擴展<br> 通過phpinfo()或命令行php -m查看是否已啟用openssl模

  2. 準備證書和私鑰<br> 可以使用OpenSSL 命令生成自簽名證書,示例

    openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
    
  3. 創建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);

三、關鍵點說明

  1. socket_export_stream()
    該函數將socket 資源轉換為PHP 的stream 資源,這樣才可以用stream_socket_enable_crypto()進行TLS 升級。

  2. stream_socket_enable_crypto()
    負責TLS 握手和加密啟動,第三個參數選擇服務端模式( STREAM_CRYPTO_METHOD_TLS_SERVER ),開啟加密。

  3. 證書配置
    stream_context_create()中傳入證書和私鑰路徑。示例中allow_self_signedverify_peer設置適合測試環境,正式環境應開啟驗證。

  4. 數據傳輸<br> 之後的數據讀寫均通過加密後的stream 進行,自動完成加密和解密


四、總結

通過socket_accept()和OpenSSL 擴展配合,PHP 可以靈活實現TLS 加密傳輸,保證數據安全。關鍵在於將socket 資源轉成stream,利用stream_socket_enable_crypto()進行加密升級,結合有效的證書管理,即可輕鬆構建安全的加密通信服務。