2012-10-02 6 views
8

PHP/cURL에서 Perl 및 LWP :: UserAgent로 응용 프로그램을 이식합니다. 웹 서버에 POST 요청을하고 클라이언트 인증서와 키 파일을 제공해야합니다. 내가 복제 할 노력하고있어 PHP 코드는 이것이다 :SSL 및 클라이언트 인증서와 함께 LWP 사용

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"); 

을 그리고 여기 내 펄 코드입니다 :

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 코드가 성공적으로 서버에 연결하지만 펄 코드와 함께 실패

SSL 읽기 오류 오류 : 14094410 : SSL 루틴 : SSL3_READ_BYTES : sslv3 경고 핸드 셰이크 실패

내가 누락 된 부분을 알아낼 수 없습니다.

+0

'private.key' (PHP)와'private.pem' (Perl)은 이식의 오타 또는 일부입니까? – amon

+2

[ssl_opts] (https://metacpan.org/module/LWP::UserAgent#ATTRIBUTES)에 여러 개의 인수를 전달하는 것은 문서화되어 있지 않습니다. 안전을 위해 ssl_opts를 여러 번 호출하거나 생성자에 전달하십시오. 나는 그것이 일하는 것이지만, 더 안전하게한다고 생각합니다. [버그/누락 된 기능으로보고] (https://rt.cpan.org/Public/Bug/Report.html?Queue=libwww-perl) 할 수도 있습니다. – Schwern

+0

그건 내가 코드를 가릴 때 오타였습니다. 둘 모두에 대해 private.key 여야합니다. 눈치 주셔서 감사하지만 그게 문제가 아니에요. 아직도 도움이 필요해! :) – kent

답변

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 [email protected] if [email protected]; 
     # 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; 
} 
3

위의 emazep의 답은 내 문제를 해결했습니다. UPS의 샘플 Perl 코드를 사용하여 XML을 통해 요금 서비스에 연결합니다. 내 테스트에서 LWP :: UserAgent가 직접 제어 할 수있는 인수없이 호출 될 때마다 작동합니다. LWP를 호출하는 다른 모듈을 사용하는 경우 편리합니다. 그냥 몇 가지 환경 변수를 (이미 LWP를 사용하고 어떤 패키지에 추가로)과 설정 순 :: SSL을 사용 : 그것은

... 
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

실제로 이것은 지저분한 비트입니다. 설정에 따라 LWP :: UserAgent는 (최소한) 두 개의 SSL 모듈 중 하나를 사용하여 SSL 연결을 처리 할 수 ​​있습니다.

  • IO :: 소켓 :: SSL
  • 순 :: 첫 번째는 LWP :: 해당 UserAgent의 최신 버전에 대한 기본이어야한다

SSL. 각 모듈에 대한 터미널에서 표준 명령을 실행하여 설치되어 이들 중 어떤 테스트 할 수 있습니다

perl -e 'use <module>;' 

IO :: 소켓 :: SSL은 예와 같이 ssl_opts와 SSL 구성이 필요합니다.

Net :: SSL은 goddogsrunnings 대답과 같이 환경 변수에서 SSL 구성을 요구합니다.

개인적으로 나는 두 번째 범주에 속하며 Crypt::SSLeay page에서 좋은 영감을 얻었습니다. 특히 "CLIENT CERTIFICATE SUPPORT"섹션.