Все шифруемые клиентские потоки теперь по умолчанию включают проверку пиров. По умолчанию сертификат пира проверяется пакетом 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-----
