PHP 大会日本 2024

SSL 上下文选项

SSL 上下文选项SSL 上下文选项列表

描述

ssl://tls:// 传输的上下文选项。

选项

peer_name 字符串

要使用的对等方名称。如果未设置此值,则根据打开流时使用的主机名猜测名称。

verify_peer 布尔值

要求验证使用的 SSL 证书。

默认为 true

verify_peer_name 布尔值

要求验证对等方名称。

默认为 true

allow_self_signed 布尔值

允许自签名证书。需要 verify_peer

默认为 false

cafile 字符串

本地文件系统上证书颁发机构文件的路径,应与 verify_peer 上下文选项一起使用以验证远程对等方的身份。

capath 字符串

如果未指定 cafile 或在其中找不到证书,则会搜索 capath 指向的目录以查找合适的证书。capath 必须是正确散列的证书目录。

local_cert 字符串

本地文件系统上本地证书文件的路径。它必须是包含您的证书和私钥的 PEM 编码文件。它可以选择包含发行者的证书链。私钥也可以包含在 local_pk 指定的单独文件中。

local_pk 字符串

如果证书 (local_cert) 和私钥使用单独的文件,则为本地文件系统上本地私钥文件的路径。

passphrase 字符串

用于对 local_cert 文件进行编码的密码短语。

verify_depth 整数

如果证书链过深,则中止。

默认为不验证。

ciphers 字符串

设置可用密码的列表。字符串的格式在 » ciphers(1) 中描述。

默认为 DEFAULT

capture_peer_cert 布尔值

如果设置为 true,则将创建包含对等方证书的 peer_certificate 上下文选项。

capture_peer_cert_chain 布尔值

如果设置为 true,则将创建包含证书链的 peer_certificate_chain 上下文选项。

SNI_enabled 布尔值

如果设置为 true,则将启用服务器名称指示。启用 SNI 允许在同一 IP 地址上使用多个证书。

disable_compression 布尔值

如果设置,则禁用 TLS 压缩。这可以帮助减轻 CRIME 攻击媒介。

peer_fingerprint 字符串 | 数组

当远程证书摘要与指定的哈希不匹配时中止。

当使用 字符串 时,长度将确定应用哪种哈希算法,即“md5”(32)或“sha1”(40)。

当使用 数组 时,键指示哈希算法名称,每个对应的值都是预期的摘要。

security_level 整数

设置安全级别。如果未指定,则使用库默认的安全级别。安全级别在 » SSL_CTX_get_security_level(3) 中描述。

从 PHP 7.2.0 和 OpenSSL 1.1.0 开始可用。

变更日志

版本 描述
7.2.0 添加了 security_level。需要 OpenSSL >= 1.1.0。

备注

注意因为 ssl://https://ftps:// 封装器的底层传输,所以适用于 ssl:// 的任何上下文选项也适用于 https://ftps://

注意要使用 SNI(服务器名称指示),PHP 必须使用 OpenSSL 0.9.8j 或更高版本编译。使用 OPENSSL_TLSEXT_SERVER_NAME 来确定是否支持 SNI。

添加注释

用户贡献的注释 9 个注释

tianyiw at vip dot qq dot com
1 年前
启用 SNI(服务器名称指示)
PEM 必须包含证书和私钥。
<?php
$context
= stream_context_create([
'ssl' => [
'SNI_enabled' => true,
'SNI_server_certs' => [
'host1.com' => '/path/host1.com.pem',
'host2.com' => '/path/host2.com.pem',
],
]
]);
?>
website at meezaan dot net
8 年前
还有一个 crypto_type 上下文。在旧版本中,这是 crypto_method。这在 https://php.net/manual/en/function.stream-socket-enable-crypto.php 中有引用
gabri dot ns at gmail dot com
4 年前
我通常从 https://curl.haxx.se/docs/caextract.html 下载根 CA 证书,然后将其作为“cafile”放入,并且几乎每次都能正常工作。

我遇到的唯一问题是当服务器没有正确发送中间 CA 证书时,那么,您必须手动将其添加到文件中。
Charlie
7 年前
我无法加载使用 stunnel 工具生成的 PEM。但是,我能够使用 PHP 调用生成一个可用的 PEM,stunnel 和 php 都能识别它,如下所述

http://www.devdungeon.com/content/how-use-ssl-sockets-php

这段代码片段现在对我有用,并且使用 stunnel verify=4,双方都确认了指纹。奇怪的是,如果在下面设置了“tls://”,则会强制使用 TLSv1,但使用“ssl://”允许使用 TLSv1.2

$stream_context = stream_context_create([ 'ssl' => [
'local_cert' => '/path/to/key.pem',
'peer_fingerprint' => openssl_x509_fingerprint(file_get_contents('/path/to/key.crt')),
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'verify_depth' => 0 ]]);

$fp = stream_socket_client('ssl://ssl.server.com:12345',
$errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream_context);
fwrite($fp, "foo bar\n");
while($line = fgets($fp, 8192)) echo $line;
Botjan kufca
14 年前
CN_match 的工作方式与直觉相反。我在使用 PHP 实现的 SSL 服务器开发时遇到了这种情况。我声明(在代码中)

- 不允许自签名证书(有效)
- 根据 CA 证书验证对等方证书(有效)
- 验证客户端的 CN 与 CN_match 是否匹配(不起作用),例如

stream_context_set_option($context, 'ssl', 'CN_match', '*.example.org');

我假设这将匹配任何 CN 在 .example.org 域名下的客户端。
不幸的是,情况并非如此。上面的选项并不会这样做。

它真正做的是
- 获取客户端的 CN 并将其与 CN_match 进行比较
- 如果客户端的 CN 包含星号,例如 *.example.org,则以通配符匹配的方式与 CN_match 进行匹配

示例来说明行为
(CNM = 服务器的 CN_match)
(CCN = 客户端的 CN)

- CNM=host.example.org, CCN=host.example.org ---> OK
- CNM=host.example.org, CCN=*.example.org ---> OK
- CNM=.example.org, CCN=*.example.org ---> OK
- CNM=example.org, CCN=*.example.org ---> ERROR

- CNM=*.example.org, CCN=host.example.org ---> ERROR
- CNM=*.example.org, CCN=*.example.org ---> OK

根据 PHP 源代码,我相信如果您尝试充当客户端并且服务器包含通配符证书,则同样适用。如果您将 CN_match 设置为 myserver.example.org 并且服务器使用 *.example.org 自我介绍,则允许连接。

以上所有内容都适用于 PHP 5.2.12 版本。
我将提供一个补丁来支持以星号开头的 CN_match。
consatangmail dot com
2 年前
建议使用 "ssl://" 传输。

在 php 5.5 ~ 7.1 中
ssl:// 传输 = ssl_v2|ssl_v3|tls_v1.0|tls_v1.1|tls_v1.2
tls:// 传输 = tls_v1.0

7.2 之后 ssl:// 和 tls:// 传输相同
php 7.2 ~ 7.3 = tls_v1.0|tls_v1.1|tls_v1.2
php 7.4 ~ 8.1 = tls_v1.0|tls_v1.1|tls_v1.2|tls_v1.3
borbas dot geri at gmail dot com
10 年前
我将此用于 Apple 推送通知服务。
通过 local_cert 选项传入本地证书文件名 `cert.pem`。
直接调用脚本时工作正常。

但是当我在不同位置包含/引用脚本时,它停止工作,没有任何明确的错误消息。

通过传入文件的完整路径 `<FullPathTo>cert.pem` 解决。
mechtecs at gmail dot com
6 年前
如果您想根据已保存的本地证书验证服务器,以进一步验证目标服务器,则必须使用 fullchain.pem。然后 verify_peer 选项将起作用。因此,只需获取服务器证书,搜索根 CA 的 pem 并将所有内容复制到单个文件中。例如

我的证书在链中具有“GeoTrust TLS RSA CA G1”证书,因此您可以在 Google 中搜索该字符串。转到官方的 DigiCert GeoTrust 页面并下载“GeoTrustTLSRSACAG1.crt”证书。然后,您可以使用以下命令将其转换为 pem 格式
openssl x509 -inform DER -in GeoTrustTLSRSACAG1.crt -out GeoTrustTLSRSACAG1.crt.pem -outform PEM
Charlie
8 年前
似乎“allow_self_signed”不适用于也不可能应用于 local_cert 选项。

Stunnel verify=4 选项(验证但忽略 CA)在这些设置中没有类似项,这很不幸。

更令人困惑的是,虽然“openssl verify -CAfile”成功,但 PHP 似乎无法在任何配置中使用新的 ca/crt 对。

我确实确实将我的 PHP 链接到 LibreSSL 2.3.8 的副本,但 PHP 奇怪地无法使用 TLS1.1 或 1.2。但是,它确实启用了 EC secp521r1(我的原生 OpenSSL 0.9.8e 无法实现)。
To Top