public function signXML($data)
    {
        $xml = new DOMDocument;
        $xml->preserveWhiteSpace = false;
        $xml->loadXML($data);

        $sig = new DOMDocument;
        $sig->preserveWhiteSpace = false;
        $sig->loadXML(
            '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                    <Reference URI="">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                        <DigestValue/>
                    </Reference>
                </SignedInfo>
                <SignatureValue/>
                <KeyInfo><KeyName/></KeyInfo>
            </Signature>'
        );

        $sig = $xml->importNode($sig->documentElement, true);
        $xml->documentElement->appendChild($sig);

        // calculate digest
        $xpath = $this->getXPath($xml);
        $digestValue = $xpath->query('ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestValue')->item(0);
        $digestValue->nodeValue = $this->generateDigest($xml);

        // calculate signature
        $signedInfo = $xpath->query('ds:Signature/ds:SignedInfo')->item(0);
        $signatureValue = $xpath->query('ds:Signature/ds:SignatureValue')->item(0);
        $signatureValue->nodeValue = $this->generateSignature($signedInfo);

        // add key reference
        $keyName = $xpath->query('ds:Signature/ds:KeyInfo/ds:KeyName')->item(0);
        $keyName->nodeValue = $this->getPublicKeyDigest();

        return $xml->saveXML();
    }