如何使用LWP :: UserAgent接受自签名证书

时间:2017-12-05 20:50:57

标签: node.js perl networking https lwp-useragent

我正在尝试设置使用HTTPS的node.js服务器。然后,我将在Perl中编写一个脚本,向服务器发出HTTPS请求,并测量往返的延迟。

这是我的node.js:

<symbol>

密钥/证书生成如下:

var express = require('express');
var https = require('https');
var fs = require('fs');

var key = fs.readFileSync('encrypt/rootCA.key');
var cert = fs.readFileSync('encrypt/rootCA.pem');

// This line is from the Node.js HTTPS documentation.
var options = {
  key: key,
  cert: cert
};

https.createServer(options, function (req, res) {
    res.writeHead(200);
    res.end("hello world - https\n");
}).listen(8088);

这是我的Perl脚本:

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

返回错误:

#!/usr/bin/perl
use LWP::UserAgent;


my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'https://127.0.0.1:8080');
my $res = $ua->request($req);

if ($res->is_success) {
  print $res->as_string;
} else {
  print "Failed: ", $res->status_line, "\n";
}

node.js文档描述了如何设置HTTPS服务器,但它在生成主证书和中间证书方面含糊不清。

https://medium.com/netscape/everything-about-creating-an-https-server-using-node-js-2fc5c48a8d4e

2 个答案:

答案 0 :(得分:6)

要使LWP :: UserAgent忽略服务器证书,请使用以下配置:

my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
    SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
    verify_hostname => 0
);

答案 1 :(得分:3)

此类问题的典型答案是完全禁用证书验证。但是,这完全不安全,基本上禁用了HTTPS提供的大部分保护。 如果验证被完全禁用,中间攻击者只能使用任意证书拦截连接并嗅探和修改数据。因此,不要这样做。

处理此类证书的正确方法是将这些证书添加为受信任的证书。这可以使用SSL_ca_file参数来完成:

my $ua = LWP::UserAgent->new;
$ua->ssl_opts(SSL_ca_file => 'rootCA.pem');
$ua->get('https://127.0.0.1:8080');

通过明确信任自签名服务器证书作为CA,它将不再抛出“证书验证失败”。

但是,除非您的服务器证书实际发布到“127.0.0.1”,否则您将获得“主机名验证失败”,因为证书的主题与URL的域不匹配。这可以通过设置预期的主机名来修复:

my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
    SSL_ca_file => 'rootCA.pem',
    SSL_verifycn_name => 'www.example.com',
);
$ua->get('https://127.0.0.1:8080');

请注意,SSL_ca_file需要自签名证书才能将CA标志设置为true,即证书是可用于颁发其他证书的CA证书。如果您的证书不是这种情况,或者您只是想接受特定证书,无论它是否已过期,已撤销,与主机名等不匹配,您可以使用证书的指纹进行验证。

my $ua = LWP::UserAgent->new;
$ua->ssl_opts(SSL_fingerprint => 'sha1$9AA5CFED857445259D90FE1B56B9F003C0187BFF')
$ua->get('https://127.0.0.1:8080');

此处的指纹与openssl x509 -noout -in rootCA.pem -fingerprint -sha1相同,只有前面添加的算法(sha1$...)和冒号被移除。