如何创建证书以使用 PHP 连接 SOAP 客户端
How to create certificate to connect with SOAP Client with PHP
提供商在 .Net 环境中有 SOAP 服务器,我必须使用 PHP 连接到它。
给定初始路径
$serviceUri = 'https://provider.com/service.svc';
$singleWsdl = 'https://provider.com/service.svc?singlewsdl';
这些网址只有在选择我的个人证书(签名)登录后才能通过浏览器访问。
我的个人证书格式为 me.pfx
,我使用以下命令分别生成私钥和 public 密钥。
$ openssl pkcs12 -in me.pfx -nocerts -nodes -out me.key
$ openssl rsa -in me.key -out me_private.key
$ openssl rsa -in me.key -pubout -out me_public.key
$ openssl pkcs8 -topk8 -inform PEM -in me_private.key -outform PEM -nocrypt
然后我复制了最后一个输出,创建了一个新的文本文件me_private_pkcs8.key
,并将所述输出粘贴到.
提供商为我的用户配置文件提供了全部权限,因此我应该能够访问 WSDL。
要么我使用错误的方式创建密钥对(从上面):
$localCert = "me_public.key";
$localKey = "me_private_pkcs8.key";
,或者我调用 SoapClient 的方式有误。我尝试了几种方法:
-
$soapClient = new \SoapClient($singleWsdl);
-
$soapClient = new \SoapClient($singleWsdl, [
'local_cert' => $localCert,
'passphrase' => '',
]);
-
$context = stream_context_create([
"ssl" => [
"local_cert" => $localCert,
"local_pk" => $localKey,
]
]);
$soapClient = new \SoapClient($singleWsdl, ["context" => $context]);
-
$opts = [
'ssl' => [
'ciphers' => 'RC4-SHA',
'verify_peer' => false,
'verify_peer_name' => false,
]
];
// SOAP 1.2 client
$params = [
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
'soap_version' => SOAP_1_1,
'trace' => 1,
'exceptions' => 1,
"connection_timeout" => 180,
'stream_context' => stream_context_create($opts),
'local_cert' => $localCert,
'passphrase' => '',
];
$soapClient = new \SoapClient($singleWsdl, $params);
-
$soapClient = new \SoapClient($singleWsdl, [
'soap_version' => 'SOAP_1_2',
'location' => $serviceUri,
'local_cert' => $localCert,
]);
-
$contextOptions = [
'ssl' => [
'local_cert' => $localCert,
'local_pk' => $localKey,
'SNI_enabled' => true,
'peer_name' => $serviceUri,
]
];
$options = [
"soap_version" => SOAP_1_2,
"features" => SOAP_SINGLE_ELEMENT_ARRAYS,
"stream_context" => stream_context_create($contextOptions),
];
$soapClient = new \SoapClient($singleWsdl, $options);
它们都会导致致命错误:
SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://provider.com/service.svc?singlewsdl' : failed to load external entity "https://provider.com/service.svc?singlewsdl" in C:\laragon\www\test-soap\private\test.php:27 Stack trace: #0 C:\laragon\www\test-soap\private\test.php(27): SoapClient->__construct('https://provide...') #1 {main}
经过 3 天的积极搜索,终于弄明白了。至少对我有用。
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());
提供商在 .Net 环境中有 SOAP 服务器,我必须使用 PHP 连接到它。
给定初始路径
$serviceUri = 'https://provider.com/service.svc';
$singleWsdl = 'https://provider.com/service.svc?singlewsdl';
这些网址只有在选择我的个人证书(签名)登录后才能通过浏览器访问。
我的个人证书格式为 me.pfx
,我使用以下命令分别生成私钥和 public 密钥。
$ openssl pkcs12 -in me.pfx -nocerts -nodes -out me.key
$ openssl rsa -in me.key -out me_private.key
$ openssl rsa -in me.key -pubout -out me_public.key
$ openssl pkcs8 -topk8 -inform PEM -in me_private.key -outform PEM -nocrypt
然后我复制了最后一个输出,创建了一个新的文本文件me_private_pkcs8.key
,并将所述输出粘贴到.
提供商为我的用户配置文件提供了全部权限,因此我应该能够访问 WSDL。
要么我使用错误的方式创建密钥对(从上面):
$localCert = "me_public.key";
$localKey = "me_private_pkcs8.key";
,或者我调用 SoapClient 的方式有误。我尝试了几种方法:
$soapClient = new \SoapClient($singleWsdl);
$soapClient = new \SoapClient($singleWsdl, [
'local_cert' => $localCert,
'passphrase' => '',
]);
$context = stream_context_create([
"ssl" => [
"local_cert" => $localCert,
"local_pk" => $localKey,
]
]);
$soapClient = new \SoapClient($singleWsdl, ["context" => $context]);
$opts = [
'ssl' => [
'ciphers' => 'RC4-SHA',
'verify_peer' => false,
'verify_peer_name' => false,
]
];
// SOAP 1.2 client
$params = [
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
'soap_version' => SOAP_1_1,
'trace' => 1,
'exceptions' => 1,
"connection_timeout" => 180,
'stream_context' => stream_context_create($opts),
'local_cert' => $localCert,
'passphrase' => '',
];
$soapClient = new \SoapClient($singleWsdl, $params);
$soapClient = new \SoapClient($singleWsdl, [
'soap_version' => 'SOAP_1_2',
'location' => $serviceUri,
'local_cert' => $localCert,
]);
$contextOptions = [
'ssl' => [
'local_cert' => $localCert,
'local_pk' => $localKey,
'SNI_enabled' => true,
'peer_name' => $serviceUri,
]
];
$options = [
"soap_version" => SOAP_1_2,
"features" => SOAP_SINGLE_ELEMENT_ARRAYS,
"stream_context" => stream_context_create($contextOptions),
];
$soapClient = new \SoapClient($singleWsdl, $options);
它们都会导致致命错误:
SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://provider.com/service.svc?singlewsdl' : failed to load external entity "https://provider.com/service.svc?singlewsdl" in C:\laragon\www\test-soap\private\test.php:27 Stack trace: #0 C:\laragon\www\test-soap\private\test.php(27): SoapClient->__construct('https://provide...') #1 {main}
经过 3 天的积极搜索,终于弄明白了。至少对我有用。
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());