現在所有加密的用戶端串流都預設啟用對等驗證。預設情況下,這將使用 OpenSSL 的預設 CA 捆綁包來驗證對等憑證。在大多數情況下,與具有有效 SSL 憑證的伺服器通訊不需要進行任何更改,因為發行商通常會將 OpenSSL 配置為使用已知的良好 CA 捆綁包。
可以透過設定 openssl.cafile 或 openssl.capath 設定,在全域範圍內覆寫預設的 CA 捆綁包,或者透過使用 cafile
或 capath
上下文選項,在每個請求的基礎上覆寫。
雖然一般不建議,但可以透過將 verify_peer
上下文選項設定為 false
來停用請求的對等憑證驗證,並透過將 verify_peer_name
上下文選項設定為 false
來停用對等名稱驗證。
已新增支援用於提取和驗證憑證指紋。新增了 openssl_x509_fingerprint() 函式以從 X.509 憑證中提取指紋,並新增了兩個 SSL 資料流上下文 選項:capture_peer_cert
用於擷取對等方的 X.509 憑證,以及 peer_fingerprint
用於斷言對等方的憑證應與給定的指紋相符。
PHP 使用的預設加密套件已更新為基於 » Mozilla 加密套件建議 的更安全列表,並額外排除兩個項目:匿名 Diffie-Hellman 加密套件和 RC4。
可以透過新的 OPENSSL_DEFAULT_STREAM_CIPHERS
常數存取此列表,並且可以透過設定 ciphers
上下文選項來覆蓋它(如同先前的 PHP 版本)。
為了減輕 CRIME 攻擊,SSL/TLS 壓縮預設已停用。PHP 5.4.13 新增了 disable_compression
上下文選項以允許停用壓縮:現在預設設定為 true
(即停用壓縮)。
已新增 honor_cipher_order
SSL 上下文選項,以允許加密資料流伺服器透過優先使用伺服器的加密套件而非用戶端的加密套件來減輕 BEAST 漏洞。
當 capture_session_meta
SSL 上下文選項設定為 true
時,現在可以透過 stream_get_meta_data() 或 stream_context_get_options() 存取已為加密資料流協商的通訊協定和加密套件。
<?php
$ctx = stream_context_create(['ssl' => [
'capture_session_meta' => TRUE
]]);
$html = file_get_contents('https://google.com/', FALSE, $ctx);
$meta = stream_context_get_options($ctx)['ssl']['session_meta'];
var_dump($meta);
?>
以上範例將輸出
array(4) { ["protocol"]=> string(5) "TLSv1" ["cipher_name"]=> string(20) "ECDHE-RSA-AES128-SHA" ["cipher_bits"]=> int(128) ["cipher_version"]=> string(11) "TLSv1/SSLv3" }
加密的用戶端串流已經支援完全前向保密 (PFS),因為它通常由伺服器控制。使用支援 PFS 的憑證的 PHP 加密伺服器串流不需要採取任何額外動作來啟用 PFS;然而,已新增許多新的 SSL 上下文選項,以便更好地控制 PFS 並處理可能發生的任何相容性問題。
現在可以透過 crypto_method
SSL 上下文選項或在建立串流包裝器時指定特定傳輸方式(例如,透過呼叫 stream_socket_client() 或 stream_socket_server())來選擇特定版本的 SSL 和 TLS。
crypto_method
SSL 上下文選項接受一個列舉允許協定的位元遮罩,stream_socket_enable_crypto() 的 crypto_type
參數也是如此。
協定 | 用戶端旗標 | 伺服器旗標 | 傳輸方式 |
---|---|---|---|
任何 TLS 或 SSL 版本 | STREAM_CRYPTO_METHOD_ANY_CLIENT |
STREAM_CRYPTO_METHOD_ANY_SERVER |
ssl:// |
任何 TLS 版本 | STREAM_CRYPTO_METHOD_TLS_CLIENT |
STREAM_CRYPTO_METHOD_TLS_SERVER |
tls:// |
TLS 1.0 | STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_0_SERVER |
tlsv1.0:// |
TLS 1.1 | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_1_SERVER |
tlsv1.1:// |
TLS 1.2 | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_2_SERVER |
tlsv1.2:// |
SSL 3 | STREAM_CRYPTO_METHOD_SSLv3_CLIENT |
STREAM_CRYPTO_METHOD_SSLv3_SERVER |
sslv3:// |
<?php
// 使用 file_get_contents() 時,要求 TLS 1.0 或更高版本:
$ctx = stream_context_create([
'ssl' => [
'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
],
]);
$html = file_get_contents('https://google.com/', false, $ctx);
// 要求 TLS 1.1 或 1.2:
$ctx = stream_context_create([
'ssl' => [
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
],
]);
$html = file_get_contents('https://google.com/', false, $ctx);
// 使用 tlsv1.2:// 串流通訊端傳輸進行連線。
$sock = stream_socket_client('tlsv1.2://google.com:443/');
?>
新增了 openssl_get_cert_locations() 函式:它會回傳 PHP 搜尋 CA 憑證包時預設搜尋的位置。
<?php
var_dump(openssl_get_cert_locations());
?>
以上範例將輸出
array(8) { ["default_cert_file"]=> string(21) "/etc/pki/tls/cert.pem" ["default_cert_file_env"]=> string(13) "SSL_CERT_FILE" ["default_cert_dir"]=> string(18) "/etc/pki/tls/certs" ["default_cert_dir_env"]=> string(12) "SSL_CERT_DIR" ["default_private_dir"]=> string(20) "/etc/pki/tls/private" ["default_default_cert_area"]=> string(12) "/etc/pki/tls" ["ini_cafile"]=> string(0) "" ["ini_capath"]=> string(0) "" }
已新增對產生、擷取和驗證已簽署公開金鑰和挑戰 (SPKAC) 的支援。新增了 openssl_spki_new()、openssl_spki_verify()、openssl_spki_export_challenge() 和 openssl_spki_export() 函式,用於從 HTML5 KeyGen
元素產生的 SPKAC 建立、驗證和匯出 PEM 公開金鑰和相關聯的挑戰。
openssl_spki_new
使用私鑰、挑戰字串和雜湊演算法產生新的 SPKAC。
<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');
$spkac = openssl_spki_new($pkey, 'challenge string');
?>
以上範例將輸出
SPKAC=MIIBXjCByDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3L0IfUijj7+A8CPC8EmhcdNoe5fUAog7OrBdhn7EkxFButUp40P7+LiYiygYG1TmoI/a5EgsLU3s9twEz3hmgY9mYIqb/rb+SF8qlD/K6KVyUORC7Wlz1Df4L8O3DuRGzx6/+3jIW6cPBpfgH1sVuYS1vDBsP/gMMIxwTsKJ4P0CAwEAARYkYjViMzYxMTktNjY5YS00ZDljLWEyYzctMGZjNGFhMjVlMmE2MA0GCSqGSIb3DQEBAwUAA4GBAF7hu0ifzmjonhAak2FhhBRsKFDzXdKIkrWxVNe8e0bZzMrWOxFM/rqBgeH3/gtOUDRS5Fnzyq425UsTYbjfiKzxGeCYCQJb1KJ2V5Ij/mIJHZr53WYEXHQTNMGR8RPm7IxwVXVSHIgAfXsXZ9IXNbFbcaLRiSTr9/N4U+MXUWL7
openssl_spki_verify
驗證提供的 SPKAC。
<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');
$spkac = openssl_spki_new($pkey, 'challenge string');
var_dump(openssl_spki_verify($spkac));
?>
openssl_spki_export_challenge
從提供的 SPKAC 匯出相關的 challenge。
<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');
$spkac = openssl_spki_new($pkey, 'challenge string');
$challenge = openssl_spki_export_challenge($spkac);
echo $challenge;
?>
以上範例將輸出
challenge string
openssl_spki_export
從 SPKAC 匯出 PEM 格式的 RSA 公開金鑰。
<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');
$spkac = openssl_spki_new($pkey, 'challenge string');
echo openssl_spki_export($spkac);
?>
以上範例將輸出
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcvQh9SKOPv4DwI8LwSaFx02h7 l9QCiDs6sF2GfsSTEUG61SnjQ/v4uJiLKBgbVOagj9rkSCwtTez23ATPeGaBj2Zg ipv+tv5IXyqUP8ropXJQ5ELtbXPUN/gvw7cO5EbPHr/7eMhbpw8Gl+AfWxW5hLW8 MGw/+AwwjHBOwong/QIDAQAB -----END PUBLIC KEY-----