6

我目前正在开发一个 WS 客户端,该客户端需要在将其请求发送到服务器之前对其进行签名。为此,我有一个私钥和一个证书,但我正在努力处理安全标头。输出 XML 的预期结构应该是这样的:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd"><wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-45..."
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd"> ... </wsse:BinarySecurityToken><ds:Signature Id="Signature-13"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-14">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>62...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
...
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-...">
<wsse:SecurityTokenReference wsu:Id="STRId-..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd"><wsse:Reference URI="#CertId-..." ValueType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature></wsse:Security></soapenv:Header>
<soapenv:Body wsu:Id="id-14" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 

我尝试使用 xmlseclibs,但我不知道如何包含所有必需的信息,因为这些示例相当基本。

我想我可以采用 DIY 方式并手动构建标头,但我希望尽可能简单。

有什么线索吗?

附加信息

我目前正在使用 SoapClient 来完成这项任务。问题是,我不知道该怎么做。我发送的 XML 需要对其内容进行签名,我已经手动完成了(使用 c14n 函数并计算其摘要 ..)。但是,为了对整个身体做同样的事情,我需要访问原始 XML(我想),所以我认为这行不通。

我没有尝试手动创建 SOAP 标头,因为我试图避免任何黑客攻击。我正在寻找既易于实施又易于工作的东西。

我的代码目前看起来像这样(将其保持在最低限度以提高可读性):

$context = stream_context_create(array(
    'ssl' => array(
        'verify_peer' => false,
        'allow_self_signed' => true,
        'ciphers'=>'SSLv3'
    )
));

$client = new SoapClient($url, array(
    //'connection_timeout' => 100,
   /* 'passphrase' => $pass,

    'local_cert' => $keystore,*/
    'stream_context' => $context,
   // 'connection_timeout' => 1,
    'trace' => true, 
    'exceptions' => true
));

$soapBody = new \SoapVar($xml, \XSD_ANYXML);

try{
    $client->__soapCall('SOMEACTION', array($soapBody));
}
catch (SoapFault $exception) {
        echo $exception->getMessage();

    }

xml变量包含我知道是正确的 XML 代码。它已经在 SoapUI(我必须提供我的密钥和密码)和我的提供商提供的在线测试服务上进行了测试。这意味着发送的数据是 100% 正确的。

但是,我的 PHP 代码以“内部错误”告终。我假设这与缺乏证书等有关。我不确定是否有办法从响应中获取更多信息,但没有关于所述错误的文档。

我一直在玩弄几种格式的选项和密钥库、私钥和证书,但没有得到任何积极的结果。我认为这一切都与没有发送正确的标题有关。

非常感谢。

4

0 回答 0