8

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

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コードがあります:

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 コードは次のエラーで失敗します。

SSL 読み取りエラー エラー:14094410:SSL ルーチン:SSL3_READ_BYTES:sslv3 アラート ハンドシェイクの失敗

何が欠けているのかわかりません。

4

3 に答える 3

2

上記の emazep からの回答で問題が解決しました。UPS のサンプル Perl コードを使用して、XML 経由で料金サービスに接続しています。私のテストから、これは直接制御できる引数なしで LWP::UserAgent が呼び出されているときはいつでも機能します。これは、LWP を呼び出す他のモジュールを使用している場合に便利です。Net::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} で指定する必要さえありません。

于 2012-11-13T17:02:12.583 に答える
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 $@ if $@;
        # 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;
} 
于 2012-10-12T12:45:35.293 に答える
1

確かにこれは厄介なビットです。セットアップに応じて、LWP::UserAgent は (少なくとも) 2 つの SSL モジュールのいずれかを使用して SSL 接続を処理します。

  • IO::ソケット::SSL
  • ネット::SSL

最初のものは、LWP::UserAgent の新しいバージョンのデフォルトである必要があります。各モジュールのターミナルで標準コマンドを実行することにより、これらのどれがインストールされているかをテストできます。

perl -e 'use <module>;'

IO::socket::SSL には、例のように ssl_opts を使用した SSL 構成が必要です。

Net::SSL では、goddogsrunnings の回答のように、環境変数に SSL 構成が必要です。

個人的に私は 2 番目のカテゴリに分類され、 Crypt::SSLeay ページから良いインスピレーションを得ました。特に「クライアント証明書のサポート」というセクション。

于 2015-09-24T12:39:43.597 に答える