Как проверить самозаверяющий сертификат? - PullRequest
0 голосов
/ 20 ноября 2018

Я использую Net::Jabber::Client для отправки сообщений через XMPP.

Сервер, к которому я подключаюсь, использует самозаверяющий сертификат:

DEBUG: .../IO/Socket/SSL.pm:2853: new ctx 45728400
DEBUG: .../IO/Socket/SSL.pm:1540: start handshake
DEBUG: .../IO/Socket/SSL.pm:717: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:750: using SNI with hostname my.host.name
DEBUG: .../IO/Socket/SSL.pm:785: request OCSP stapling
DEBUG: .../IO/Socket/SSL.pm:806: set socket to non-blocking to enforce timeout=10
DEBUG: .../IO/Socket/SSL.pm:819: call Net::SSLeay::connect
DEBUG: .../IO/Socket/SSL.pm:822: done Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:832: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:842: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:862: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:819: call Net::SSLeay::connect
DEBUG: .../IO/Socket/SSL.pm:2754: did not get stapled OCSP response
DEBUG: .../IO/Socket/SSL.pm:2707: ok=0 [0] /CN=my.host.name/CN=my.host.name
DEBUG: .../IO/Socket/SSL.pm:822: done Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:825: SSL connect attempt failed

DEBUG: .../IO/Socket/SSL.pm:825: local error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:828: fatal SSL error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:1963: downgrading SSL only, not closing socket
DEBUG: .../IO/Socket/SSL.pm:2875: free ctx 45728400 open=
DEBUG: .../IO/Socket/SSL.pm:2879: free ctx 45728400 callback
DEBUG: .../IO/Socket/SSL.pm:2886: OK free ctx 45728400

Я обнаружил, что могу передать SSL_fingerprint и / или SSL_verifycn_name чтобы пройти проверку самозаверяющего сертификата.

Чтобы все заработало, я взломал этот

my %ssl_params = (
    SSL_verify_mode => $self->{SIDS}->{newconnection}->{ssl_verify},
    SSL_hostname    => 'my.host.name',
    SSL_verifycn_name => 'my.host.name',
);

без успеха = (

Я пытаюсь использовать ->get_fingerprint, чтобы получить отпечаток пальца и передать его параметру SSL_fingerprint, но:

IO::Socket::SSL->start_SSL(
    $self->{SIDS}->{$sid}->{sock},
    $self->{SIDS}->{$sid}->{ssl_params}
) or die "$IO::Socket::SSL::SSL_ERROR";

завершится ошибкой:

SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed at

Какойвозможность перейти на IO::Socket::SSL для проверки самозаверяющего сертификата?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Использование отпечатка пальца, вероятно, самый простой способ проверить самозаверяющий сертификат, который находится под вашим собственным контролем.При использовании SSL_fingerprint он не будет заботиться о каких-либо других видах проверок, т. Е. Больше не будет проверять имя, отзыв, истечение срока действия и т. Д., Поэтому, если вы хотите иметь проверки для этого, вам не следует использовать SSL_fingerprint.

Получение отпечатка пальца сайта можно выполнить, подключившись к сайту один раз без проверки (так как вы еще не доверяете сертификату) и получив отпечаток пальца или получив отпечаток пальца непосредственно из сертификата.

Чтобы получить отпечаток пальца, запрашивая сервер, предполагая, что соединение не перехватывается, чтобы вы получили правильный отпечаток пальца:

use IO::Socket::SSL;
print IO::Socket::SSL->new(
    PeerHost => 'example.com:443',
    # switch off validation since the certificate is not trusted yet
    SSL_verify_mode => SSL_VERIFY_NONE,
)->get_fingerprint,"\n";

В настоящее время это дает sha256$642de54d84c30494157f53f657bf9f89b4ea6c8b16351fd7ec258d556f821040, который можно напрямую использовать в качестве аргумента для SSL_fingerprint.

Если у вас уже есть сертификат для сайта, вы можете вычислить отпечаток непосредственно на нем:

# get the certificate
$ openssl s_client -connect example.com:443 -servername example.com 
...
-----BEGIN CERTIFICATE-----
MIIF8jCCBNqgAwIBAgIQDmTF+8I2reFLFyrrQceMsDANBgkqhkiG9w0BAQsFADBw
...
-----END CERTIFICATE-----

# take this PEM certificate and get fingerprint
$ openssl x509 -fingerprint -sha256 -noout -in cert.pem
SHA256 Fingerprint=64:2D:E5:4D:84:C3:04:94:15:7F:53:F6:57:BF:9F:89:B4:EA:6C:8B:16:35:1F:D7:EC:25:8D:55:6F:82:10:40

Показанный отпечаток практически такой же, как и раньше, только написанный на другомпуть.Удаляя все ':' (которые есть только для удобства чтения), вы получаете 642DE5....1040, а с префиксом к используемому алгоритму хеширования sha256 вы получаете что-то, что можно использовать в SSL_fingerprint: sha256$642DE5...1040.

Чтобы использовать отпечаток пальца, а затем подключиться к сайту:

my $cl = IO::Socket::SSL->new(
    PeerHost => 'example.com:443',
    SSL_fingerprint => 'sha256$642DE5...1040'
);
0 голосов
/ 20 ноября 2018

IO::Socket::SSL может проверить самозаверяющий сертификат, только если он доверяет файлу центра сертификации, который вы используете для самостоятельной подписи сертификата .

Я думаю, вам нужно правильно передать SSL_ca_fileили SSL_ca_path до IO::Socket::SSL, чтобы файл центра сертификации был доступен для него.Это первое, что упомянуто в общих ошибках использования разделе IO::Socket::SSL документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...