【发布时间】:2018-09-29 18:57:17
【问题描述】:
我需要使用 PHP7.2 请求 https://address?wsdl 的 SOAP 请求 .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);
?>
【问题讨论】:
-
你必须在 CURL 请求中使用什么代码才能使用该证书但不起作用?
-
插入了一些代码和结果。我应该首先这样做:)
-
看过并尝试过这个?似乎你在混合命令参数 - stackoverflow.com/questions/27062639/…
-
是的,我做到了。到处都有很多误导性的答案,包括 curl 不接受 p12 证书。卷曲和肥皂都为我工作。 SOAP 使用
stream_context_create,它允许我设置allow_self_signed=true。所以我真正遇到的最后一个问题是:SSL certificate problem: self signed certificate in certificate chain。现在我必须找出如何忽略这个问题(不仅仅是我有解决方法)。之后,我将发布我如何解决 curl 和 soap 的所有.p12问题。如果您能帮我解决这个自签名证书,我会很高兴。 -
stackoverflow.com/questions/21187946/… ?看来您需要更加注意并检查证书链,因为它告诉您,而不是尝试解决它。