如何验证自签名证书?
How to verify self-signed certificate?
我使用 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
and/orSSL_verifycn_name
来通过自签名证书的验证
为了让它正常工作,我破解了 this
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
以验证自签名证书?
IO::Socket::SSL
只有在信任您用于 self sign the certificate.
的证书颁发机构文件时,才能验证自签名证书
我认为您需要将正确的 SSL_ca_file
或 SSL_ca_path
传递给 IO::Socket::SSL
以便它可以访问证书颁发机构文件。这是 IO::Socket::SSL
文档的 common usage errors 部分中提到的第一件事。
使用指纹可能是验证您自己控制的自签名证书的最简单方法。当使用 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";
目前给出的 sha2562de54d84c30494157f53f657bf9f89b4ea6c8b16351fd7ec258d556f821040
可以直接用作 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
中可用的东西:sha2562DE5...1040
.
要使用指纹然后连接到站点:
my $cl = IO::Socket::SSL->new(
PeerHost => 'example.com:443',
SSL_fingerprint => 'sha2562DE5...1040'
);
通常这发生在通过本地主机加密时,证书本身几乎不起任何作用。
涉及 IO::Socket::SSL 的模块可以与附加参数一起使用,以防止 "certificate verify failed".
崩溃
要长期解决该问题,请在顶部添加以下行:
use IO::Socket::SSL qw(SSL_VERIFY_NONE);
$smtp = Net::SMTPS->new('localhost',
doSSL => 'starttls',
Port => 587,
SSL_verify_mode => SSL_VERIFY_NONE
);
我使用 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
and/orSSL_verifycn_name
来通过自签名证书的验证
为了让它正常工作,我破解了 this
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
以验证自签名证书?
IO::Socket::SSL
只有在信任您用于 self sign the certificate.
我认为您需要将正确的 SSL_ca_file
或 SSL_ca_path
传递给 IO::Socket::SSL
以便它可以访问证书颁发机构文件。这是 IO::Socket::SSL
文档的 common usage errors 部分中提到的第一件事。
使用指纹可能是验证您自己控制的自签名证书的最简单方法。当使用 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";
目前给出的 sha2562de54d84c30494157f53f657bf9f89b4ea6c8b16351fd7ec258d556f821040
可以直接用作 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
中可用的东西:sha2562DE5...1040
.
要使用指纹然后连接到站点:
my $cl = IO::Socket::SSL->new(
PeerHost => 'example.com:443',
SSL_fingerprint => 'sha2562DE5...1040'
);
通常这发生在通过本地主机加密时,证书本身几乎不起任何作用。
涉及 IO::Socket::SSL 的模块可以与附加参数一起使用,以防止 "certificate verify failed".
崩溃要长期解决该问题,请在顶部添加以下行:
use IO::Socket::SSL qw(SSL_VERIFY_NONE);
$smtp = Net::SMTPS->new('localhost',
doSSL => 'starttls',
Port => 587,
SSL_verify_mode => SSL_VERIFY_NONE
);