Lari13
Lari13

Reputation: 1870

How to sign SOAP message in php

I'm using php (yii2) and I'd like to implement SOAP communication with server. I have following guide to SOAP:

The Customer’s system uses the Customer’s private key for issuing digital signatures. Both the application request (ApplicationRequest) and the SOAP message must be signed separately in the WSC. The signature is performed with the private key. The signing system must include in the signature also the certificate. This certificate contains the public key corresponding to the private key used in the signing. The receiver uses the public key to authenticate the signature.

and:

Next step: Digitally sign (detached type XML Digital Signature) the whole SOAP message with the Private Key of Sender Certificate and put the signature into SOAP-header

So, I have own private.key, public.key and certificate.cer

My code looks like

    $client = new SoapClient($wdsl, ['trace' => true]);
    $arguments = ['DownloadFileListRequest' => $dflr];
    $appResponse = $client->__call('downloadFileList', $arguments);

But I get the expected error:

SOAP signature error

What I have to do and how to sign this SOAP?

Upvotes: 1

Views: 4053

Answers (1)

Lari13
Lari13

Reputation: 1870

XMLSecurityDSig helped (https://github.com/robrichards/xmlseclibs)

$dom = new DOMDocument('1.0', 'UTF-8');
$ar = $dom->createElementNS('http://bxd.fi/xmldata/', 'ApplicationRequest');
$dom->appendChild($ar);
$ar->appendChild($dom->createElement('CustomerId', $this->userID));
...
$ar->appendChild($dom->createElement('Content', $contentBase64));

$objDSig = new XMLSecurityDSig();
$objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
$objDSig->addReference(
            $dom,
            XMLSecurityDSig::SHA256,
            ['http://www.w3.org/2000/09/xmldsig#enveloped-signature'],
            ['force_uri' => true]
        );
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type'=>'private']);
$objKey->loadKey($this->privateKeyPath, true);
$objDSig->sign($objKey);
$objDSig->add509Cert(base64_encode(file_get_contents($this->certificatePath)), false);
$objDSig->appendSignature($dom->documentElement);

$xmlRaw = $dom->saveXML();

Upvotes: 1

Related Questions