我在使用新的LWP(6.x)时遇到了使用PKCS12证书的困难。基本上,这段代码在perl5.8.8和旧版Crypt::SSLeay(版本0.57)和LWP(版本5.826)下可以运行:
local $ENV{HTTPS_PKCS12_PASSWORD} = $sslPassword;
local $ENV{HTTPS_PKCS12_FILE} = $pkcs12_cert;
my $response = LWP::UserAgent->new->request(POST($url, Content => $content));
但是在perl5.14.2和最新版本的Crypt::SSLeay 0.64以及LWP (6.03)中不起作用。
所谓“不起作用”,是指我收到了一个HTTP::Response对象,例如:
bless( {
'_content' => 'Can\'t connect to host:port
',
'_rc' => 500,
'_headers' => bless( {
'client-warning' => 'Internal response',
'client-date' => 'Thu, 27 Sep 2012 18:28:34 GMT',
'content-type' => 'text/plain'
}, 'HTTP::Headers' ),
'_msg' => 'Can\'t connect to host:port',
'_request' => ...
)
我知道LWP中与SSL相关的代码最近有很多变化;PKCS12支持是否仍然有效?为了让证书和密码被识别,我应该设置不同的变量/选项吗?
我还尝试将其传递给LWP::UserAgent->new,但没有成功:
ssl_opts => {
SSL_use_cert => 1,
SSL_cert_file => $pkcs12_cert,
SSL_passwd_cb => sub { $sslPassword },
}
跟进:我将PKCS12证书转换为PEM格式:
openssl pkcs12 -in my_pkcs12.p12 -out mycert.pem -clcerts -nokeys
openssl pkcs12 -in my_pkcs.p12 -out mykey.pem -nocerts
<passphrase entered>
并且可以通过以下方式使用新文件:
curl -k --cert mycert.pem --key mykey.pem --pass passphrase --cert-type PEM https://url
...并在测试脚本中设置这些环境变量:
$ENV{HTTPS_CERT_FILE} = 'mycert.pem';
$ENV{HTTPS_KEY_FILE} = 'mykey.pem';
......而且在较旧的LWP下也能正常工作,但在新的LWP下则无法正常工作。因此,至少它不是与PKCS12证书相关的特定问题,而是SSL处理方式在内部发生了更根本性的变化。