2012-10-02 62 views
8

私はPHP/cURLからPerlとLWP :: UserAgentにアプリケーションを移植しています。 WebサーバーにPOSTリクエストを行い、クライアント証明書とキーファイルを提供する必要があります。私は複製しようとしているPHPコードはこれです:SSLとクライアント証明書でLWPを使用する

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コードがで失敗します:

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のコードです

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を呼び出す他のモジュールを使用している場合は便利です。ただ、ネット:: 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

実際、これは面倒なビットです。設定に応じて、LWP :: UserAgentはSSL接続を処理するために(少なくとも)2つのSSLモジュールのいずれかを使用することがあります。

  • IO ::ソケット:: SSL
  • ネット::最初のものはLWP :: UserAgentのの新しいバージョンのデフォルトであるべき

SSL。あなたは、各モジュール用の端末で標準のコマンドを実行してインストールされているこれらのどのテストすることができます。

perl -e 'use <module>;' 

IO ::ソケット:: SSLはあなたの例のようにssl_optsとSSLの設定が必要です。

Net :: SSLでは、goddogsrunnings answerのように環境変数にSSL設定が必要です。

個人的に私は第2カテゴリーに入り、Crypt::SSLeay pageから良いインスピレーションを得ました。特に、「CLIENT CERTIFICATE SUPPORT」というセクション。

関連する問題