Все шифруемые клиентские потоки теперь по умолчанию включают проверку пиров. По умолчанию сертификат пира проверяется пакетом OpenSSL CA. Обычно не нужно ничего делать для соединения с серверами с правильным SSL-сертификатом, так как OpenSSL настроен так, что уже работает с хорошими CA-пакетами.
Стандартный CA пакет может быть переопределён глобально с помощью
установки или openssl.cafile или openssl.capath строк конфигурации,
или же на уровне каждого запроса используя опции контекста
cafile
или
capath
.
Хотя это и не рекомендуется, но можно отключить проверку сертификата пира
для запроса, установив verify_peer
опцию контекста в false
, и можно отключить проверку имени пира, установив
verify_peer_name
в false
.
Была добавлена поддержка извлечения и проверки сигнатуры сертификата.
Для извлечения сигнатур сертификатов X.509 добавлена функция
openssl_x509_fingerprint(). Также были добавлены две
опции контекста потока SSL:
capture_peer_cert
для захвата узлового сертификата X.509,
и peer_fingerprint
для проверки сертификата на соответствие
заданной сигнатуре.
Список шифров по умолчанию, используемых PHP, был обновлён на более безопасный в соответствии с » рекомендациями по шифрам от Mozilla, с двумя дополнительными исключениями: анонимные шифры Диффи-Хеллмана и RC4.
Этот список доступен через новую константу
OPENSSL_DEFAULT_STREAM_CIPHERS
, и может быть переопределён
(как и в предыдущих версиях PHP) установкой опцией контекста
ciphers
.
Сжатие SSL/TLS было запрещено по умолчанию для compression уменьшения
вероятности атаки типа CRIME. В PHP 5.4.13 была добавлена опция контекста
disable_compression
для возможности запретить компрессию и теперь она по умолчанию установлена
как true
(то есть компрессия запрещена).
Была добавлена опция контекста honor_cipher_order
,
которая позволяет серверу обслуживающему зашифрованный поток самому
определять шифры, которыми будет пользоваться клиент. Это позволить снизить
риск атаки типа BEAST.
Протокол и шифр, согласованные для шифрованного потока, доступны
с помощью функций stream_get_meta_data() или
stream_context_get_options(), если опция контекста SSL
capture_session_meta
установлена как true
.
<?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" }
Шифрованные потоки клиента уже поддерживают совершенную прямую секретность, поскольку она, как правило, контролируется сервером. Серверы PHP, обслуживающие шифрованные потоки, использующие сертификаты поддерживающие совершенную прямую секретность не нуждаются в каких либо дополнительных действиях для включения PFS; однако, было добавлено некоторое количество новых опций контекста SSL для более точного контроля над PFS и для решения возможных проблем.
ecdh_curve
Эта опция позволяет выбрать кривую для использования в шифрах ECDH.
Если не задано, то будет использоваться prime256v1
.
dh_param
Путь к файлу, содержащему параметры для обмена ключами Диффи-Хеллмана, созданного, например, с помощью такой команды:
openssl dhparam -out /path/to/my/certs/dh-2048.pem 2048
single_dh_use
Если установлено как true
, новая пара ключей будет создана, используя
параметры Диффи-Хеллмана, тем самым улучшая прямую секретность.
single_ecdh_use
Если установлено как true
, новая пара ключей будет генерироваться всегда,
при согласовании шифра ECDH. Это улучшает прямую секретность.
Теперь возможно выбирать конкретную версию SSL и TLS с помощью опции
контекста crypto_method
или указывая конкретный
транспорт при создании обёртки потока (например с помощью вызова
stream_socket_client() или
stream_socket_server()).
Опция контекста SSL crypto_method
принимает битовую
маску, перечисляющую допустимые протоколы, также как это задаётся в
параметре crypto_type
функции
stream_socket_enable_crypto().
Протокол | Флаг клиента | Флаг сервера | Транспорт |
---|---|---|---|
Любые версии 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
// Требуется TLS 1.0 или выше для использования file_get_contents():
$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() для создания, проверки экспорта PEM
публичных ключей и соответствующих опознавательных строк из SPKAC,
созданных из элементов HTML5 KeyGen
.
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.
<?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
Экспорт публичного ключа (PEM) RSA в формате из SPKAC.
<?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-----