Проверка ЦС PHP и SSL - Не зависит от операционной системы
Вот простой PHP-скрипт, который открывает SSL-сокет, готовый для отправки HTTP-запросов:
$contextOptions = array(); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
Это работает - я только что протестировал его, - но нет проверки в доверенном хранилище ЦС.
Мы можем изменить этот скрипт, чтобы использовать параметры контекста SSL PHP :
$contextOptions = array( 'ssl' => array( 'cafile' => 'C:\xampp\cacerts.pem', 'CN_match' => '*.google.com', // CN_match will only be checked if 'verify_peer' is set to TRUE. See https://bugs.php.net/bug.php?id=47030. 'verify_peer' => TRUE, ) ); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
Пока "cafile" существует и имеет правильный CA, этот пример также работает...
...но как мы можем сделать это без жесткого кодирования имени файла/пути к файлу CA? Мы пытаемся создать что-то, что проверяет сертификаты SSL независимо от операционной системы, не требуя отдельной настройки для каждого сервера, на котором выполняется этот сценарий.
Я знаю, что в Linux есть каталог для CAS, который мы могли бы поместить как "capath". А как насчет Окон? Где он хранит свои доверенные центры сертификации? Я искал, и они, к сожалению, оказались в реестре, так что мы никак не можем получить к ним доступ с PHP? Как насчет других операционных систем?
1 answers
Проигранная битва...
Невозможно выполнить безопасную зашифрованную передачу в PHP без ручной настройки параметров контекста "cafile"
и "CN_match"
до PHP 5.6. И, к сожалению, даже если вы правильно установите эти значения, ваши передачи все равно с большой вероятностью завершатся неудачей, потому что версии до 5.6 не консультируются со все более популярным расширением SAN (subjectAltName), присутствующим в одноранговых сертификатах при проверке имен хостов. В результате "безопасное" шифрование встроенные в PHP обертки потоков в значительной степени являются неправильным названием. Ваша самая безопасная ставка (буквально) с более старыми версиями PHP - это расширение curl.
Что касается сертификатов Windows...
Windows использует собственное хранилище сертификатов и кодирует свои сертификаты в формате, отличном от OpenSSL. Для сравнения, приложения openssl используют open.Формат PEM. Версии PHP до версии 5.6 не могут каким-либо образом взаимодействовать с хранилищем сертификатов Windows. По этой причине невозможно иметь надежные и безопасное шифрование в кросс-операционной системе с использованием встроенной функции оболочки потока.
PHP 5.6 - это важный шаг вперед
Новые директивы openssl.cafile и openssl.capath php.ini позволяют глобально назначать местоположения сертификатов, не устанавливая их в каждом контексте потока
Все зашифрованные потоки по умолчанию проверяют сертификаты одноранговых узлов и имена хостов, и имя хоста автоматически анализируется из URI, если параметр контекста
"CN_match"
отсутствует предоставленный.Потоковые криптографические операции теперь проверяют записи SAN однорангового сертификата при проверке имен хостов
Если в контексте потока не указан файл/путь CA или директив php.ini, PHP автоматически возвращается в хранилища сертификатов операционной системы (в Windows тоже!)
В качестве примера, это все, что вам нужно сделать, чтобы безопасно подключиться к github.com в PHP-5.6:
<?php
$socket = stream_socket_client("tls://github.com:443");
Да. Это действительно так. Никакой суеты по поводу настройки контекста и параметры проверки. В этом отношении PHP теперь работает так же, как ваш браузер.
Больше чтения на эту тему
Эти изменения PHP 5.6 являются лишь верхушкой айсберга в отношении улучшений SSL/TLS. Мы упорно трудились, чтобы сделать 5.6 самым безопасным выпуском PHP на сегодняшний день в отношении зашифрованных сообщений.
Если вы хотите узнать больше об этих новых функциях, есть множество информации, доступной через официальный каналы
- [ RFC] Улучшенные значения по умолчанию TLS
- [ RFC] Одноранговая проверка TLS
- 5.6 Файл НОВОСТЕЙ
- 5.6 ОБНОВЛЕНИЕ файла
Примечание о соответствии SAN в 5.4/5.5
Мы работаем над тем, чтобы перенести, по крайней мере, соответствие SAN в ветви 5.4 и 5.5, поскольку без этой функции чрезвычайно сложно использовать оболочки шифрования каким-либо значимым образом (в качестве клиента). Хотя эта работа по бэкпорту в значительной степени зависит от моего свободного времени в качестве волонтера, и этот ответ, безусловно, может помочь этому произойти раньше:)