web-dev-qa-db-ja.com

証明書を使用したPHP SOAPリクエストの作成

通信用にサービスをロックダウンするために、自己署名証明書を持つ.NETWebサービスへのPHP SOAP接続を作成しようとしています。 HTTPS。引き続きエラーが発生しますが、証明書の作成方法、Apache/PHPの設定、SOAP)の確立方法と関係があるかどうかわかりません。リクエストか何か他のもの。誰かが何かポインタを持っているなら、彼らは大いに感謝されるでしょう。よろしくお願いします。

証明書の生成

これが私が証明書を作成する方法です。

  1. 信頼されたルート秘密鍵を作成します。

    genrsa -out ca_authority_prv.pem 2048

  2. 信頼されたルート権限証明書を作成します。

    req -new -key ca_authority_prv.pem -x509 -out ca_authority_cert.pem

  3. 証明書機関を信頼できるものにします。

    x509 -in ca_authority_cert.pem -out ca_authority_trust.pem -trustout

  4. OpenSSLを終了し、シリアルファイルを作成します。

    エコー1000> ca_authority.srl

  5. クライアントの秘密鍵を作成します。

    genrsa -out Client_prv.pem 2048

  6. クライアントリクエストを作成します。

    req -new -key Client_prv.pem -out Client_req.pem

  7. CAを使用してクライアント要求に署名します。

    x509 -req -CA ca_authority_trust.pem -CAserial ca_authority.srl -CAkey ca_authority_prv.pem -in Client_req.pem -out Client_cert.pem

  8. クライアント証明書のpfxを作成します

    pkcs12 -export -in Client_cert.pem -inkey Client_prv.pem -out Client_cert.pfx

IISセットアップ

この証明書が作成されたら、サーバー証明書に対して同じ手順を実行します。

  1. 信頼されたルートCAをマシンの信頼されたルートストアに追加します

  2. サーバー証明書をマシンストアに追加します

  3. サーバー証明書を使用してクライアント証明書を要求するには、セットアップIIS

PHP SOAPリクエスト

これは、PHP SOAPリクエストを確立するために使用しているコードです(以下はエラーです):

$wsdl = "https://localhost/MyService/MyService.asmx";
$local_cert = "C:\\Certs\client_cert.pem";
$passphrase = "openSaysMe";

    $soapClient = new SoapClient($wsdl, array('local_cert'=>  $local_cert,'passphrase'=>$passphrase));
    $theResponse = $soapClient->test();

エラー

Warning: SoapClient::SoapClient() [soapclient.soapclient]: Unable to set private key file `C:\Certs\client_cert.pem' in C:\Program Files\Apache Group\Apache2\htdocs\soapWithAuth.php on line 53

Warning: SoapClient::SoapClient() [soapclient.soapclient]: failed to create an SSL handle in C:\Program Files\Apache Group\Apache2\htdocs\soapWithAuth.php on line 53

Warning: SoapClient::SoapClient() [soapclient.soapclient]: Failed to enable crypto in C:\Program Files\Apache Group\Apache2\htdocs\soapWithAuth.php on line 53

Warning: SoapClient::SoapClient(https://localhost/MyService/MyService.asmx) [soapclient.soapclient]: failed to open stream: operation failed in C:\Program Files\Apache Group\Apache2\htdocs\soapWithAuth.php on line 53

Warning: SoapClient::SoapClient() [soapclient.soapclient]: I/O warning : failed to load external entity "https://localhost/MyService/MyService.asmx" in C:\Program Files\Apache Group\Apache2\htdocs\soapWithAuth.php on line 53
Error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://localhost/MyService/MyService.asmx'

エラーログ

PHP Warning:  SoapClient::SoapClient() [<a href='soapclient.soapclient'>soapclient.soapclient</a>]: failed to create an SSL handle in C:\\Program Files\\Apache Group\\Apache2\\htdocs\\soapWithAuth.php on line 54
11
likestoski

私はなんとかこれを機能させることができましたが、私が疑問に思ういくつかの奇妙なことがあります。具体的には、クライアント証明書と秘密鍵を1つのファイルに結合して、Soapリクエストと一緒に送信する必要があり、証明書のパスフレーズはリクエストを壊していましたが、PHP Soapドキュメントにはオプションとして明示的に含まれています。誰かがこれを改善する方法について意見を持っているなら、私はそれを聞きたいです。

1)OpenSslクライアントおよびサーバー証明書を作成し、認証局で署名します。証明書を作成するときは、パスフレーズを割り当てないでください。その時点でEnterボタンを押すだけです。

2)サーバー認証局ファイルを信頼されたルートの下のマシン証明書ストアにインポートします。これを行うには、コマンドプロンプトでMMCコマンドを使用し、証明書スナップインを追加します。

3)サーバー証明書をマシンストア個人証明書ストアにインポートします

4)ローカルアカウントのパーソナルストアにクライアント証明書をインポートします。これを行うには、コマンドプロンプトでcertmgr.mscと入力します。

5)PHPのSSLバージョンでApacheが実行されていることを確認します。 PHPの非phpバージョンがすでにインストールされている場合は、次の手順に従って、SSLを使用して実行するようにApacheサーバーを構成できます。

内部httpd.conff

a) Remove the comment ‘#’ at line : LoadModule ssl_module modules/mod_ssl.so

b) Remove the comment ‘#’ at the line inside `<IfModule ssl_module>`:  Include /extra/httpd-ssl.conf

   and move this line after the block `<IfModule ssl_module>…. </IfModule>`  

内部php.ini

c) Remove the comment ‘;’ at the line which says: extension=php_openssl.dll

6)次の手順を使用して、証明書とSSLを使用するようにIISを構成します。

a) Right click the 'Default Website' node choose 'Properties'

b) 'Directory Security' tab 'Server Certificate' button. Follow the wizard to select the certificate you imported into the store then complete the wizard and return to the 'Directory Security' tab.

c) Under 'Secure Communications' select the 'Edit' button. 

d) Check the 'Require Secure Channel (SSL) checkbox.

7)PHP SOAPリクエストの作成(test()メソッドはWebサービスで有効なメソッドである必要があります):

$wsdl = "https://localhost/MyService/myservices.asmx?wsdl";
$local_cert = "C:\\SoapCerts\ClientKeyAndCer.pem";

$soapClient = new SoapClient($wsdl, array('local_cert' => $local_cert));

$theResponse = $soapClient->test();

8)このファイルをApacheディレクトリに配置します。デフォルト: 'C:\ Program Files\Apache Group\Apache2\htdocs'

9)クライアント証明書にアクセスする必要があります。クライアント証明書とサーバー証明書を作成するために行った手順では、秘密鍵ファイルも作成しました。 client_prv.pem(クライアント秘密鍵ファイル)を開き、テキストエディターを使用して内容を新しいドキュメントにコピーします。特殊文字の束を追加しないテキストパッドのようなものを使用する方がおそらく安全です。証明書パーサーは非常にうるさいです。秘密鍵部分の直後に、クライアント証明書(client_cer.pem)の内容を配置して、結果のファイルがクライアントの秘密鍵とクライアントのエスケープされていないコピーになるようにします。

証明書。結果のファイルを、phpファイルからアクセスできるディレクトリに保存します。上記の例では、結果のファイルは

'C:\ SoapCerts\ClientKeyAndCer.pem'ファイル。

9)localhost /nameOfYourFile.phpに移動します。サービスへの接続が成功し、期待される結果と一致する応答が表示されるはずです。

Webサービス方式。

16
likestoski

補足:成功させる方法がありますSOAPリクエストおよび秘密鍵と証明書ファイルを分離しておくこれを行うには、ストリームコンテキストを作成する必要がありますそしてそれをcontextオプションとして渡します。

  <?php

  $wsdl = "https://localhost/MyService/MyService.asmx";
  $context = stream_context_create(
    array(
     "ssl" => array(
     "local_cert" => "C:\\Certs\client_cert.pem",
     "local_pk"   => "/path/to/private/key"
      )
    )
  );

   $client = new \SoapClient($wsdl, array("context" => $context));
0
bodi0