当前位置: 首页> 最新文章列表> socket_accept() + TLS 实现数据加密传输(结合 OpenSSL 扩展)

socket_accept() + TLS 实现数据加密传输(结合 OpenSSL 扩展)

M66 2025-06-01

在 PHP 中,利用 socket_accept() 接受客户端连接后,结合 OpenSSL 扩展实现 TLS 加密传输,是提升网络通信安全性的常用方法。本文将介绍如何用原生 socket 接口与 OpenSSL 扩展配合,实现基于 TLS 的加密传输。

一、准备工作

  1. 确保 PHP 支持 OpenSSL 扩展
    通过 phpinfo() 或命令行 php -m 查看是否已启用 openssl 模块。

  2. 准备证书和私钥
    可以使用 OpenSSL 命令生成自签名证书,示例:

    openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
    
  3. 创建 socket 服务器
    使用 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. 数据传输
    之后的数据读写均通过加密后的 stream 进行,自动完成加密和解密。


四、总结

通过 socket_accept() 和 OpenSSL 扩展配合,PHP 可以灵活实现 TLS 加密传输,保证数据安全。关键在于将 socket 资源转成 stream,利用 stream_socket_enable_crypto() 进行加密升级,结合有效的证书管理,即可轻松构建安全的加密通信服务。