我正在尝试更新一个简单的 Perl 子例程,让我们的程序连接到巴西政府的服务器以上传发票。今天运行正常,如下图:
use WWW::Curl::Easy;
my $curl = WWW::Curl::Easy->new;
my $response_body;
my @param = ('Content-Type: application/soap+xml; charset=utf-8', "SOAPAction: '$action''");
$curl->setopt(CURLOPT_URL, "$urlsefaz"); # one of Brazil's SEFAZ URLs
$curl->setopt(CURLOPT_PORT , 443);
$curl->setopt(CURLOPT_VERBOSE, 0);
$curl->setopt(CURLOPT_HEADER, 1);
$curl->setopt(CURLOPT_SSLVERSION, 3);
$curl->setopt(CURLOPT_SSL_VERIFYHOST, 0);
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 0);
$curl->setopt(CURLOPT_SSLCERT, "$certificate");
$curl->setopt(CURLOPT_SSLKEY, "$privateKey");
$curl->setopt(CURLOPT_POST, 1);
$curl->setopt(CURLOPT_POSTFIELDS, $data);
$curl->setopt(CURLOPT_HTTPHEADER, \@param);
$curl->setopt(CURLOPT_WRITEDATA,\$response_body);
my $responsexml = $curl->perform;
但是,巴西政府更新了他们的安全政策,在他们的下一次更新中他们将不再接受 SSLv3 连接,只接受 TLS 1.2,这导致我当前尝试与新测试服务器的连接失败。
根据MetaCPAN Documentation on WWW::Curl ,其中包括 WWW::Curl::Easy 的示例,方法 setopt
应该采用“大多数”libcurl
参数。我相信它正确地采用了 CURLOPT_SSLVERSION
,而不是采用 CURLOPT_SSLVERSION's documentation 中描述的常量之一。 ,执行这段代码的程序员决定将等效值通知给其中一个选项(大概是 SSLv3)?
因此,我不知道应该将什么值传递给 CURLOPT_SSLVERSION
以通知此模块使用 TLS 1.2,或者如何通知正确的常量。或者我可以设置另一个 setopt
参数以使其与 TLS 1.2 一起使用吗?
此外,如果没有解决方法,我正在考虑围绕另一个库从头开始创建一个新函数 - 也许 LWP::UserAgent
?这是最好的方法吗?是否有其他库更适合处理此问题?
提前感谢您的任何想法。
最佳答案
只需删除行设置 CURLOPT_SSLVERSION
!默认的 libcurl 无论如何都会尝试协商正确的版本,因此通常不需要也不需要特定的选择。
数字 3 来自 this list 中的 SSLv3 (在 libcurl 头文件中)。第一个条目是 0,第二个条目是 1 等等。
要明确要求 TLS 1.2(或更高版本),要使用的符号是 CURL_SSLVERSION_TLSv1_2
但我建议不要要求特定版本,只要您没有到。请注意,此符号首先在 libcurl 7.34.0 中引入。
关于perl - 更新 WWW::Curl::Easy to work with TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50763488/