我正在将应用程序从PHP / cURL移植到Perl和LWP :: UserAgent。我需要向Web服务器发出POST请求并提供客户端证书和密钥文件。我试图复制的PHP代码是:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSLCERT, "/path/to/certificate.pem");
curl_setopt($ch, CURLOPT_SSLKEY, "/path/to/private.key");
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, "secretpassword");
这是我的Perl代码:
my $ua = LWP::UserAgent->new();
$ua->ssl_opts(
SSL_verify_mode => 0,
SSL_cert_file => '/path/to/certificate.pem',
SSL_key_file => "/path/to/private.key",
SSL_passwd_cb => sub { return "secretpassword"; }
);
PHP代码成功连接到服务器,但Perl代码失败了:
SSL读取错误错误:14094410:SSL例程:SSL3_READ_BYTES:sslv3警报握手失败
我无法弄清楚我错过了什么。
答案 0 :(得分:3)
以上emazep的回答解决了我的问题。我正在使用来自UPS的示例Perl代码通过XML连接到他们的Rate服务。从我的测试中,只要你没有可以直接控制的参数调用LWP :: UserAgent,这就行了。如果你正在使用其他模块为你调用LWP,这会很方便。只需使用Net :: SSL(除了已经使用LWP的任何软件包之外)并设置一些环境变量:
...
use Net::SSL;
$ENV{HTTPS_VERSION} = 3;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $browser = LWP::UserAgent->new();
...
就是这样!您甚至不需要使用$ ENV {PERL_LWP_SSL_CA_FILE}指定服务器根证书的路径。
答案 1 :(得分:2)
sub send_command(){
my $command = shift;
my $parser = XML::LibXML->new('1.0','utf-8');
print color ("on_yellow"), "SEND: ", $command, color ("reset"), "\n";
# Create a request
my $req = HTTP::Request->new( GET => $Gateway.$command );
# Pass request to the user agent and get a response back
my $res;
eval {
my $ua;
local $SIG{'__DIE__'};
$ua = LWP::UserAgent->new(); # или
$ua->ssl_opts( #$key => $value
SSL_version => 'SSLv3',
SSL_ca_file => '/ca.pem',
#SSL_passwd_cb => sub { return "xxxxx\n"; },
SSL_cert_file => '/test_test_cert.pem',
SSL_key_file => '/test_privkey_nopassword.pem',
); # ssl_opts => { verify_hostname => 0 }
$ua->agent("xxxxxx xxxx_tester.pl/0.1 ");
$res = $ua->request($req);
};
warn $@ if $@;
# Check the outcome of the response
if ( $res->is_success ) {
open xxxLOG, ">> $dir/XXXX_tester.log";
my $without_lf = $res->content;
$without_lf =~ s/(\r|\n)//gm;
print PAYLOG $without_lf,"\n";
close PAYLOG;
}
else {
return $res->status_line;
}
print color ("on_blue"), "RESPONSE: ", color ("reset"), respcode_color($res->content), color ("reset"),"\n\n";
return $res->content;
}
答案 2 :(得分:1)
确实这是一个混乱的一点。根据您的设置,LWP :: UserAgent可以使用(至少)两个SSL模块中的一个来处理SSL连接。
第一个应该是较新版本的LWP :: UserAgent的默认值。您可以通过在每个模块的终端中运行标准命令来测试安装了哪些:
perl -e 'use <module>;'
IO :: socket :: SSL需要使用ssl_opts进行SSL配置,如示例所示。
Net :: SSL需要环境变量中的SSL配置,如goddogsrunnings的回答。
就个人而言,我属于第二类,并从Crypt::SSLeay page获得了很好的灵感。特别是名为&#34; CLIENT CERTIFICATE SUPPORT&#34;。
的部分