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
): 整数|布尔值

启用或禁用流上的加密。

一旦建立了加密设置,可以通过在 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 个注释

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

如果套接字处于非阻塞模式,则 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
匿名
2 年前
如果您需要在处理未加密流量后将流从未加密更改为加密,则在读取未加密流量时使用 stream-socket-recvfrom 函数读取而不是 fread。使用 fread 会导致初始 CLIENT HELLO 消息的一些缓冲区读入其缓冲区,从而导致 SSL 握手在某些情况下失败。
2
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 握手,`stream_socket_enable_crypto` 在客户端发送 `Client HELLO` 后发送 `Server HELLO`。

因此,在接受客户端连接后,使用 `STREAM_CRYPTO_METHOD_*_CLIENT` 请求数据,使用 `STREAM_CRYPTO_METHOD_*_SERVER` 提供数据。
1
Zero
1 年前
从 PHP 7.2 开始,TLS 等同于 TLS_ANY,因此 `STREAM_CRYPTO_METHOD_TLS_CLIENT` 表示任何 TLS 版本。
To Top