首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何验证自签署证书?

如何验证自签署证书?
EN

Stack Overflow用户
提问于 2018-11-20 19:30:40
回答 3查看 2.4K关注 0票数 2

我使用Net::Jabber::Client通过XMPP发送消息。

连接到的服务器使用自签名证书:

代码语言:javascript
复制
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来通过自我签名证书的验证。

为了让它正常工作,我黑了

代码语言:javascript
复制
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参数,但是:

代码语言:javascript
复制
IO::Socket::SSL->start_SSL(
    $self->{SIDS}->{$sid}->{sock},
    $self->{SIDS}->{$sid}->{ssl_params}
) or die "$IO::Socket::SSL::SSL_ERROR";

因错误而失败:

代码语言:javascript
复制
SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed at

传递给IO::Socket::SSL以验证自签名证书的哪个选项?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-11-23 04:14:19

使用指纹可能是验证由您自己控制的自签名证书的最简单方法。在使用SSL_fingerprint时,它将不再关心任何其他类型的验证,即不再检查名称、撤销、过期等--因此,如果您也希望对此进行检查,则不应该使用SSL_fingerprint

获取站点的指纹可以通过在没有验证的情况下连接到站点一次(因为您还没有信任证书)和获取指纹,或者直接从证书中获取指纹。

若要通过询问服务器获取指纹,假设连接没有被截获,那么您可以获得正确的指纹:

代码语言:javascript
复制
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的参数。

如果您已经拥有该站点的证书,则可以直接在其上计算指纹:

代码语言:javascript
复制
# 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_fingerprintsha256$642DE5...1040中使用。

要使用指纹连接到站点,请执行以下操作:

代码语言:javascript
复制
my $cl = IO::Socket::SSL->new(
    PeerHost => 'example.com:443',
    SSL_fingerprint => 'sha256$642DE5...1040'
);
票数 3
EN

Stack Overflow用户

发布于 2018-11-20 20:03:07

只有当IO::Socket::SSL信任用于自签证书的证书颁发机构文件时,它才能验证自签名证书。

我认为您需要将正确的SSL_ca_fileSSL_ca_path传递给IO::Socket::SSL,这样它才能访问证书颁发机构文件。这是常见使用错误文档的IO::Socket::SSL部分中提到的第一件事。

票数 1
EN

Stack Overflow用户

发布于 2020-02-16 22:36:48

通常,这发生在通过本地主机进行加密时,其中证书本身几乎不起作用。

涉及IO::Socket::SSL的模块可以与附加参数一起使用,以防止出现“证书验证失败”的崩溃。

为了长期解决这一问题,在最上面添加以下一行:

代码语言:javascript
复制
use IO::Socket::SSL qw(SSL_VERIFY_NONE);

$smtp = Net::SMTPS->new('localhost',
   doSSL => 'starttls',
   Port => 587,
   SSL_verify_mode => SSL_VERIFY_NONE
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53400241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档