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 备注

website at meezaan dot net
7 年前
还有一个 crypto_type 上下文。在旧版本中,这是 crypto_method。这在 https://php.net/manual/en/function.stream-socket-enable-crypto.php 上有所提及。
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',
],
]
]);
?>
gabri dot ns at gmail dot com
4 年前
我通常从 https://curl.haxx.se/docs/caextract.html 下载根 CA 证书,然后将其作为 'cafile' 放置,它几乎总是有效的。

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

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;
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
Botjan kufca
14 年前
CN_match 的工作方式与直觉相反。我在开发 PHP 实现的 SSL 服务器时遇到了这个问题。我在代码中声明了

- 不允许自签名证书(有效)
- 使用 CA 证书验证对等证书(有效)
- 使用 CN_match 验证客户端的 CN(无效),例如

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 ---> 错误

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

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

以上所有内容适用于 PHP 5.2.12 版本。
我将提供一个补丁来支持以星号开头的 CN_match。
borbas dot geri at gmail dot com
10 年前
我将其用于 Apple 推送通知服务。
通过 local_cert 选项传递本地证书文件名 `cert.pem`。
直接调用脚本时,效果很好。

但是,当我从其他位置包含/加载该脚本时,它停止工作,没有任何明确的错误消息。

通过传递文件的完整路径 `<FullPathTo>cert.pem` 来解决。
mechtecs at gmail dot com
5 年前
如果您想根据已保存的本地证书验证服务器,以进一步验证目标服务器,则必须使用 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
7 年前
似乎 "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