簡體   English   中英

使用證書創建 PHP SOAP 請求

[英]Creating a PHP SOAP request with a certificate

我正在嘗試創建到具有自簽名證書的 .NET Web 服務的 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

我設法讓這個工作,但有一些我想知道的奇怪之處。 特別是需要將客戶端證書和私鑰組合到一個文件中以與 Soap 請求以及證書密碼短語一起發送,這破壞了請求,盡管 PHP Soap 文檔明確將其作為一個選項包含在內。 如果有人對如何改進這一點有意見,我很樂意聽到。

1) 創建 OpenSsl 客戶端和服務器證書,並使用證書頒發機構對其進行簽名。 創建證書時不要為它們分配密碼,只需在此時按下 Enter 按鈕即可。

2) 將服務器證書頒發機構文件導入受信任根下的 Machine 證書庫中。 您可以通過在命令提示符下使用 MMC 命令然后添加證書管理單元來實現這一點。

3)將Server證書導入Machine store Personal證書存儲

4) 在本地賬戶個人存儲中導入客戶端證書。 您可以通過在命令提示符下鍵入 certmgr.msc 來執行此操作。

5) 確保運行帶有 SSL 版本的 PHP 的 Apache。 如果您已經安裝了非 php 版本的 PHP,您可以按照以下步驟配置您的 Apache 服務器以使用 SSL 運行。

httpd.conf里面

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) 使用以下步驟將 IIS 配置為使用證書和 SSL:

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(客戶端私鑰文件)並使用文本編輯器將內容復制到新文檔中。 使用像 Textpad 這樣的東西可能更安全,它希望不會添加一堆特殊字符,證書解析器非常挑剔。 在私鑰部分之后立即放置客戶端證書 (client_cer.pem) 的內容,以便生成的文件是客戶端私鑰和客戶端的未轉義副本

證書。 將生成的文件保存到您可以從 php 文件訪問的目錄中。 在上面的例子中,結果文件是

'C:\\SoapCerts\\ClientKeyAndCer.pem' 文件。

9) 導航到 localhost/nameOfYourFile.php。 您應該看到與服務的成功連接,其響應與您的預期結果相匹配

網絡服務方法。

旁注:有一種方法,使成功的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));

gitbash

$ cd path/to/certificate/
$ openssl pkcs12 -in personal_certificate.pfx -out public_key.pem -clcerts

首先您必須輸入YOUR_CERT_PASSWORD一次,然后輸入DIFFERENT_PASSWORD! 兩次。 可以訪問代碼的每個人都可以使用后者。

PHP

<?php

$wsdlUrl   = "https://example.com/service.svc?singlewsdl";
$publicKey = "rel/path/to/certificate/public_key.pem";
$password  = "DIFFERENT_PASSWORD!";

$params = [
    'local_cert' => $publicKey,
    'passphrase' => $password,
    'trace' => 1,
    'exceptions' => 0
];

$soapClient = new \SoapClient($wsdlUrl, $params);

var_dump($soapClient->__getFunctions());
var_dump($soapClient->__getTypes());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM