我需要SOAP请求https://address?wsdl
,它需要使用PHP7.2的.p12
证书。
经过几个小时的研究,我唯一能做的就是从bash提出这个请求:
$ curl -k -E cert.crt.pem --key cert.key.pem https://address?wsdl
这使WSDL退缩了。但我必须将.p12
拆分为单独的文件并使用-k
选项,这使得所有这些东西都不安全。通过以下命令完成拆分:
openssl pkcs12 -in mycert.p12 -out cert.key.pem -nocerts -nodes
openssl pkcs12 -in mycert.p12 -out cert.crt.pem -clcerts -nokeys
问题是:如何使用PHP中的cURL
请求此WSDL或如何配置new \SoapClient()
以便它可以工作?
这可能只有.p12
文件和密码?或者我必须转换它?
希望这能描述我已经能够做到的事情:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_VERBOSE, true);
/**
* cert.p12 (with password) -> cert.pem (contains encrypted PKey & client ?unencrypted? cert)
* $ openssl pkcs12 -in cert.p12 -out cert.pem -clcerts
*
* Result:
*
* This works. But:
* - I don't have peer verification
* - Is such file safe? It has encrypted pkey & certificate (I think not encrypted).
* I don't know much about that topic. Maybe someone with more experience will be able to tell more.
* Maybe some better solution to output this. Maybe as 2 separate files?
*/
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); // DO NOT VERIFY!
curl_setopt($ch,CURLOPT_SSLCERT,__DIR__ . '/cert.pem');
//curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pass); // This is not required :/
curl_setopt($ch,CURLOPT_SSLKEY,__DIR__ . '/cert.pem');
curl_setopt($ch,CURLOPT_SSLKEYPASSWD, $pass);
/**
* cert.p12 (with password) -> cert.pem (contains encrypted PKey & client ?unencrypted? cert)
* $ openssl pkcs12 -in cert.p12 -out cert.pem -clcerts
*
* Result:
*
* TCP_NODELAY set
* Connected to XXX
* ALPN, offering http/1.1
* SSL certificate problem: self signed certificate in certificate chain
* stopped the pause stream!
* Closing connection 0
*/
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_SSLCERT,__DIR__ . '/cert.pem');
curl_setopt($ch,CURLOPT_SSLKEY,__DIR__ . '/cert.pem');
curl_setopt($ch,CURLOPT_SSLKEYPASSWD, $pass);
/**
* cert.p12 (with password) -> cert.pem (contains encrypted PKey & client ?unencrypted? cert)
* $ openssl pkcs12 -in cert.p12 -out cert.pem -clcerts
*
* Result:
*
* TCP_NODELAY set
* Connected to XXX
* ALPN, offering http/1.1
* ignoring certificate verify locations due to disabled peer verification
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* stopped the pause stream!
* Closing connection 0
*/
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch,CURLOPT_CAINFO,__DIR__ . '/cert.pem');
curl_setopt($ch,CURLOPT_CAPATH,__DIR__);
curl_setopt($ch,CURLOPT_KEYPASSWD,$pass);
/**
* cert.p12 (with password) -> cert.pem (contains encrypted PKey & client ?unencrypted? cert)
* $ openssl pkcs12 -in cert.p12 -out cert.pem -clcerts
*
* Result:
*
* TCP_NODELAY set
* Connected to XXX
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /www/soap/cert.pem
* CApath: /www/soap
* SSL certificate problem: self signed certificate in certificate chain
* stopped the pause stream!
* Closing connection 0
*/
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch,CURLOPT_CAINFO,__DIR__ . '/cert.pem');
curl_setopt($ch,CURLOPT_CAPATH,__DIR__);
curl_setopt($ch,CURLOPT_KEYPASSWD,$pass);
$data = curl_exec($ch);
$error = curl_error($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
var_dump($data, $httpcode, $error);
?>