PHP Conference Japan 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 (伺服器名稱指示) 可用,則必須使用 OpenSSL 0.9.8j 或更高版本編譯 PHP。使用 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.dev.org.tw/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_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 ---> 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