private function signXML($xmlRequest)
    {
        $xmlRequestDOMDoc = new DOMDocument();
        $xmlRequestDOMDoc->loadXML($xmlRequest);

        $canonical = $xmlRequestDOMDoc->C14N();
        $digestValue = base64_encode(hash('sha1', $canonical, true));
        $rootElem = $xmlRequestDOMDoc->documentElement;

        /** @var \DOMElement $signatureNode Signature node */
        $signatureNode = $rootElem->appendChild(new DOMElement('Signature'));
        $signatureNode->setAttribute('xmlns', 'http://www.w3.org/2000/09/xmldsig#');

        /** @var \DOMElement $signedInfoNode Signed info node */
        $signedInfoNode = $signatureNode->appendChild(new DOMElement('SignedInfo'));
        $signedInfoNode->setAttribute('xmlns', 'http://www.w3.org/2000/09/xmldsig#');

        /** @var \DOMElement $canonicalMethodNode Canonicalization method node */
        $canonicalMethodNode = $signedInfoNode->appendChild(new DOMElement('CanonicalizationMethod'));
        $canonicalMethodNode->setAttribute('Algorithm', 'http://www.w3.org/2001/10/xml-exc-c14n#');

        /** @var \DOMElement $signatureMethodNode Signature method node */
        $signatureMethodNode = $signedInfoNode->appendChild(new DOMElement('SignatureMethod'));
        $signatureMethodNode->setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#rsa-sha1');

        /** @var \DOMElement $referenceNode */
        $referenceNode = $signedInfoNode->appendChild(new DOMElement('Reference'));
        $referenceNode->setAttribute('URI', sprintf('#%s', $xmlRequestDOMDoc->documentElement->getAttribute('Id')));

        /** @var \DOMElement $transformsNode */
        $transformsNode = $referenceNode->appendChild(new DOMElement('Transforms'));

        /** @var \DOMElement $transform1Node */
        $transform1Node = $transformsNode->appendChild(new DOMElement('Transform'));
        $transform1Node->setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#enveloped-signature');

        /** @var \DOMElement $transform2Node */
        $transform2Node = $transformsNode->appendChild(new DOMElement('Transform'));
        $transform2Node->setAttribute('Algorithm', 'http://www.w3.org/2001/10/xml-exc-c14n#');

        /** @var \DOMElement $digestMethodNode */
        $digestMethodNode = $referenceNode->appendChild(new DOMElement('DigestMethod'));
        $digestMethodNode->setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#sha1');
        $referenceNode->appendChild(new DOMElement('DigestValue', $digestValue));

        $signedInfoNode = $xmlRequestDOMDoc->getElementsByTagName('SignedInfo')->item(0);
        $signatureNode = $xmlRequestDOMDoc->getElementsByTagName('Signature')->item(0);

        $signatureValueNode = new DOMElement(
            'SignatureValue',
            base64_encode($this->generateSignature($signedInfoNode))
        );
        $signatureNode->appendChild($signatureValueNode);
        $keyInfoNode = $signatureNode->appendChild(new DOMElement('KeyInfo'));
        $x509DataNode = $keyInfoNode->appendChild(new DOMElement('X509Data'));

        $x509CertificateNode = new DOMElement('X509Certificate', $this->getPublicCertificateString());
        $x509DataNode->appendChild($x509CertificateNode);
        $x509IssuerSerialNode = $x509DataNode->appendChild(new DOMElement('X509IssuerSerial'));

        $x509IssuerNameNode = new DOMElement('X509IssuerName', $this->getCertificateIssuerName());
        $x509IssuerSerialNode->appendChild($x509IssuerNameNode);

        $x509SerialNumberNode = new DOMElement('X509SerialNumber', $this->getCertificateIssuerSerialNumber());
        $x509IssuerSerialNode->appendChild($x509SerialNumberNode);

        return $this->plainXML($xmlRequestDOMDoc);
    }