Я пытаюсь подключиться к защищенной веб-розетке, созданной PHP, но по какой-то причине это не работает.Файлы сертификатов доступны для чтения на PHP.
Пока это мой код (сторона PHP; упрощенный код):
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'allow_self_signed', false);
stream_context_set_option($context, 'ssl', 'verify_peer', true);
stream_context_set_option($context, 'ssl', 'peer_name', 'example.com');
stream_context_set_option($context, 'ssl', 'CN_match', 'example.com');
stream_context_set_option($context, 'ssl', 'SNI_enabled', true);
stream_context_set_option($context, 'ssl', 'local_cert', '/path/to/ssl/cert/example.com');
stream_context_set_option($context, 'ssl', 'local_pk', '/path/to/ssl/private/example.com');
$serverSocket = stream_socket_server(
'tls://example.com:8090',
$errNo,
$errStr,
\STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN,
$context
);
$client = stream_socket_accept($serverSocket);
// send initial websocket connection stuff
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
'H*',
sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= 'Sec-WebSocket-Version: 13' . "\r\n";
$headers .= 'Sec-WebSocket-Accept: ' . $key . "\r\n\r\n";
socket_write($client, $headers, \mb_strlen($headers));
// do something here...
socket_close($client);
socket_close($serverSocket);
На стороне клиента:
var con = new WebSocket('wss://' + host + ':' + port);
var $chat = $('#chat');
con.onmessage = function(e) {
$chat.append('<p>' + e.data + '</p>');
};
con.onopen = function(e) {
con.send('Hello Me!');
};
con.onclose = function (e) {
console.log('connection closed.', arguments);
}
У меня нет файла * .pem.Только два файла, которые используются на веб-сервере Apache.Было бы возможно преобразовать эти файлы в файл pem, если это необходимо.Но я думаю, что они должны работать в php с этими обоими файлами, не так ли?
Для лучшего тестирования мы используем изолированный поддомен с сертификатом Let's шифрования.Потому что мы получили полный доступ к этому серверу.Однако из генератора сертификатов я получил только те два упомянутых файла.Для веб-сервера это работает отлично.Но как сделать то же самое для веб-сокета в php?
Теперь, с помощью этого кода, после отправки некоторых сообщений клиенту серверный скрипт сообщает мне, что он не смог получить одноранговый узел из сертификатов.Я не знаю, что означает это сообщение и как это исправить.Я также уже пытался обменяться local_cert
и local_pk
друг с другом, но это все равно не помогло.
Edit: После исследования, оказывается, что phpСбой при каждой комбинации с другой ошибкой.
Мои сгенерированные файлы сертификатов выглядят так:
Файл / opt / psa / var / сертификаты / cert-0x8zHR:
-----BEGIN CERTIFICATE REQUEST-----
some letters
-----END CERTIFICATE REQUEST-----
-----BEGIN PRIVATE KEY-----
some letters
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
some letters
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
some letters
-----END CERTIFICATE-----
Файл / opt / psa / var / сертификаты / cert-Du9H8N:
-----BEGIN CERTIFICATE-----
some letters
-----END CERTIFICATE-----
Все строки из строк сертификатов из обеих из них заканчиваются в позиции символа65.
Как вы можете прочитать в документации php, php ожидает получить файл в формате PEM: http://php.net/manual/en/context.ssl.php#context.ssl.local-cert
Я нашел это руководство, чтобы преобразовать мои два файла в один файл PEM, номои сертификаты выглядят иначе, чем упомянуто на сайте, а также я не знаю, что именно включить в файл PEM, что нужно php: https://www.digicert.com/ssl-support/pem-ssl-creation.htm
Edit 2: Как указано нижеВот точные ошибки, которые я получаю:
с
stream_context_set_option($cont, 'ssl', 'local_pk', '/opt/psa/var/certificates/cert-0x8zHR');
stream_context_set_option($cont, 'ssl', 'local_cert', '/opt/psa/var/certificates/cert-Du9H8N');
Предупреждение: stream_socket_accept (): невозможно установить файл закрытого ключа `/ opt / psa / var / сертификаты / cert-0x8zHR 'в ... on line ...
Предупреждение: stream_socket_accept (): не удалось включить шифрование в... on line ...
Предупреждение: stream_socket_accept (): принять не удалось: Успех в ... on line ...
Предупреждение: socket_read () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
Примечание: неопределенное смещение: 1 in ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсомлогическое значение указано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
предупреждение: socket_write() ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение указывается в ... on line ...
Предупреждение: socket_write ()ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_close () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
И с
stream_context_set_option($cont, 'ssl', 'local_cert', '/opt/psa/var/certificates/cert-0x8zHR');
stream_context_set_option($cont, 'ssl', 'local_pk', '/opt/psa/var/certificates/cert-Du9H8N');
Предупреждение: stream_socket_accept (): невозможно установить файл закрытого ключа `/ opt / psa / var / сертификаты / cert-Du9H8N 'в ...on line ...
Предупреждение: stream_socket_accept (): не удалось включить шифрование в ... on line ...
Внимание: stream_socket_accept (): accept fail: Success in ...on line ...
Предупреждение: socket_read () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
Примечание: неопределенное смещение: 1 in ...on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсным, логическое значениезадано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_write ()ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ...on line ...
Предупреждение: socket_close () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
И с (просто конкатенациейcert-0x8zHR с cert-Du9H8N)
$file = dirname(__FILE__, 3) . \DIRECTORY_SEPARATOR . 'fullchain.pem';
stream_context_set_option($cont, 'ssl', 'local_cert', $file);
Предупреждение: stream_socket_accept (): не удалось получить сертификат однорангового узла в ... ...
Предупреждение: stream_socket_accept ():Не удалось включить шифрование в ... ...
Предупреждение: stream_socket_accept (): принять не удалось: Успех в ... ...
Предупреждение: socket_read () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
Примечание: неопределенное смещение: 1 in ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение указано в ... on line ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение указано в... ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом,логическое значение задано в ... ...
Предупреждение: socket_write () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... ...
предупреждение: socket_write () ожидает параметр 1быть ресурсом, логическое значение задано в ... ...
Предупреждение: socket_close () ожидает, что параметр 1 будет ресурсом, логическое значение задано в ... on line ...
Редактировать 3: Да, действительно, есть ошибка openssl.После третьего socket_stream_accept
предупреждения я теперь получаю эту ошибку, просто используя код из примера php doc:
error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch
Я искал эту ошибку в Интернете.Говорят, если появляется эта ошибка, я выбрал неверный файл сертификата.
Кроме того, если я проигрываю эту команду:
openssl x509 -noout -in cert-0x8zHR -modulus
Я получил две разные строки для модуля.Но я не знаю почему, ни как это исправить.Оба эти файла используются в конфигурации vhost веб-сервера apache и работают нормально:
SSLEngine on
SSLVerifyClient none
SSLCertificateFile /opt/psa/var/certificates/cert-0x8zHR
SSLCACertificateFile /opt/psa/var/certificates/cert-Du9H8N
PS: Если вам известен какой-либо инструмент для локального преобразования в файл pem, пожалуйста, дайте мне знать.Онлайн конвертация невозможна.