【问题标题】:How to use LWP with client cert and CA如何将 LWP 与客户端证书和 CA 一起使用
【发布时间】:2015-07-16 23:59:53
【问题描述】:

我现在有一些 perl 代码退出到 shell 以调用 curl 与带有证书的端点对话。这很好用,但是当我逃到 shell 并采取简单的选择时,我总是觉得我在使用 perl 作弊。下面是我正在使用的 curl 命令,它工作正常。

$soap_response = echo '$soap_request' | curl --cacert $self->{'server_cert'} --cert $self->{'client_cert'} -d '\@-' -H 'SOAPAction:urn:anonOutInOp' $self->{'end_point'} -s | xmllint -format -;

我有一个 CA 文件和一个客户端文件,都是 PEM 格式的。

我曾尝试使用 LWP 和 Net::SSL 纯粹在 perl 中进行这种通信,并摆脱对 curl 的依赖,但我一辈子都无法让它工作。

我将 Net:SSL 的环境设置为

#set up the ssl envrioment for Net::SSL
$ENV{HTTPS_DEBUG} = 1;
$ENV{HTTPS_CERT_FILE} = $client_cert;
$ENV{HTTPS_CA_FILE}   = $server_cert;
$ENV{HTTPS_CA_DIR}    = $certificate_dir;

然后将我的请求发送为

my $ua = new LWP::UserAgent();
my $request = HTTP::Request->new(POST => $endpoint);
$request->header(SOAPAction => '"query"');
$request->content($query);
$request->content_type("text/xml; charset=utf-8");

my $response = $ua->request($request);
print $response->content,"\n";

我运行时得到的输出是

SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:HTTP</faultcode><faultstring>(403)Forbidden</faultstring><detail><ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">hh0pgw01</ns2:hostname><ns3:HttpErrorCode xmlns:ns3="http://xml.apache.org/axis/">403</ns3:HttpErrorCode></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

所以它似乎交换了 CA 文件并且对主机很满意,但是我的请求随后被 403 禁止错误拒绝,我怀疑这与我的客户端密钥没有与请求正确交换有关。

谁能帮我解决这个问题或建议它可能在哪里崩溃。

【问题讨论】:

    标签: perl ssl curl lwp lwp-useragent


    【解决方案1】:

    所以它似乎交换了 CA 文件并且对主机很满意,但是我的请求随后被 403 禁止错误拒绝,我怀疑这与我的客户端密钥没有与请求正确交换有关。

    看起来客户端发送了一个证书并且服务器接受了它。因为否则 SSL 握手将失败,在这种情况下,服务器将无法发送 403 甚至一些 XML。因此,可能是服务器端应用程序没有将必要的权限与您发送的证书相关联,即这是错误的证书或服务器配置错误。

    也可能是您的请求是错误的。在查看 curl 和 LWP 请求时,我觉得您正在发送与 SOAP 相关的不同标头。

    除此之外,您似乎使用的是非常旧版本的 LWP,或者明确强制使用已弃用且不安全的 Net::SSL/Crypt::SSL 后端。当前版本的 LWP(版本>=6.0,即过去 4 年内的所有内容)不使用 Net::SSL/Crypt::SSLeay,而是使用 IO::Socket::SSL 作为后端。要配置它,请使用ssl_opts,然后使用为 IO::Socket::SSL 记录的相关 SSL 选项:

     LWP::UserAgent->new(..., ssl_opts => {
          SSL_ca_path   => ... # directory with CA, if file use SSL_ca_file
          SSL_cert_file => ... # the client site certificate
          SSL_cert_key  => ... # the key for the client site certificate
     });
    

    【讨论】:

    • 我有 6.05 版的 LWP,但在使用 ssl_opts 时我不断收到握手错误。证书是正确的,因为当我使用 curl 运行它们时它可以工作。我也试过改变肥皂头,没有区别
    • 根据使用 Net::SSL 的调试输出,该站点仅使用 SSL 3.0,由于 POODLE 攻击,自 10/2015 起默认情况下被 IO::Socket::SSL 禁用。您可以在ssl_opts 中使用SSL_version =&gt; 'SSLv3' 明确强制执行它。除了查看服务器端的日志消息之外,为什么服务器认为您的证书不能用于授权。
    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 2010-12-24
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多