4

我从提供商那里得到了两个证书文件,一个是 .cer 格式,一个是 .p7b 格式。然后我将 p7b 证书转换为 p12 证书。有了这个证书,我就可以从我的浏览器连接到 wsdl。然后我继续使用我在此站点上找到的一些说明将该证书转换为 .pem 格式。

openssl pkcs12 -clcerts -nokeys -out test.pem -in mycert.p12
openssl pkcs12 -nocerts -out key.pem -in mycert.p12

然后使用以下命令将证书与密钥结合起来:

cat test.pem key.pem > cert.pem

这是我对 Web 服务类的构造:

public function __construct() {
    $wsdl_url = 'https://url.to/web_service?wsdl';
    $pass = 'passphrase';
    $cert = 'cert.pem';

    try {
        $this->client = new SoapClient($wsdl_url, array('local_cert' => $cert, 'passphrase' => $pass));
    } catch(SoapFault $e) {
        print_r($e);
    }
}

这是错误:

SSL operation failed with code 1. OpenSSL Error messages: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca in /var/www/html/..

尝试使用以下方法验证证书:

openssl verify cert.pem

给我以下错误:

error 20 at 0 depth lookup:unable to get local issuer certificate

我还尝试使用以下 openssl 命令创建 .pem-certificate:

openssl pkcs12 -in mycert.p12 -out mycert.pem

验证这一点给了我 OK,但 PHP 给了我以下错误:

Unable to set local cert chain file `mycert.pem'; Check that your cafile/capath settings include details of your certificate and its issuer

我假设应该可以让它以某种方式工作,因为我可以通过浏览器访问 wsdl,使用 .p12 证书。但我无法找到关于我应该如何进行的解决方案。提前致谢。

4

2 回答 2

0

我认为它无法找到颁发您提供的证书的根证书。

证书通常由签名机构签署和颁发,您的客户需要知道签名机构的公钥。如果您的证书是自签名证书,则无关紧要。

去检查 openssl x509 -text -noout -in key.pem

检查输出并查找 Issuer。如果颁发者与证书的 CN 不同,则您需要来自提供证书的签名机构的根证书。

您通常可以通过使用浏览器打开 wsdl 地址并检查证书链并从层次结构选项卡中导出根证书来获取它。

我不确定在你的情况下将它保存在哪里,但会有一些东西指向某种类型的信任库。

于 2010-10-29T07:32:44.820 回答
0

我认为你在这里有一些问题。首先,我不认为 SoapClient 对象的构造函数正在使用您的本地证书选项。options 数组不支持 SSL 配置选项。其次,鉴于您提供给 SoapClient 的选项没有被使用,Open SSL 抱怨远程主机上的证书是自我认证的证书。

我认为应该可以解决这个问题,但如果不使用代码,我无法确定所有选项。我认为您需要使用 stream_context_create() 创建自定义流上下文来设置所需的 SSL 选项(查看http://ca.php.net/stream_context_create和 SSL 的上下文选项)。然后可以将其作为配置数组中的 stream_context 选项传递给 SoapClient 对象。使用 stream_context 您可以设置您需要的各种 SSL 选项,这些选项将覆盖默认值。

很抱歉,我无法更准确地了解您需要设置的选项。希望使用流上下文可以解决您的问题。

于 2010-09-27T16:37:46.837 回答