SOAP request signing in net core fails the verification why?

33 views Asked by At

I have following code c# code.

 public string SignXml(string xml, X509Certificate2 cert)
    {
        if (xml == null)
            throw new ArgumentException(nameof(xml));

        if (string.IsNullOrEmpty(_appSettings.EncryptedKeyPassword))
            throw new ArgumentException(nameof(_appSettings.EncryptedKeyPassword));


        XmlDocument xmlDoc = new XmlDocument { PreserveWhitespace = true };
        xmlDoc.LoadXml(xml);

        string privateKey = File.ReadAllText(_appSettings.PrivateKeyFilePath);
        RSACryptoServiceProvider rsaKey = DecodeRsaPrivateKey(privateKey, _appSettings.EncryptedKeyPassword);

        SignedXml signedXml = new SignedXml(xmlDoc);
        signedXml.SigningKey = rsaKey;
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";

        KeyInfo keyInfo = new KeyInfo();

        KeyInfoX509Data x509Data = new KeyInfoX509Data(cert);
        x509Data.AddIssuerSerial(cert.IssuerName.Format(false), cert.SerialNumber);
        keyInfo.AddClause(x509Data);

        signedXml.KeyInfo = keyInfo;
        signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";

        Reference reference = new Reference();
        reference.Uri = "#Body";  
        reference.AddTransform(new XmlDsigC14NTransform());
        reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1";

        signedXml.AddReference(reference);

        signedXml.ComputeSignature();

        XmlElement signedElement = signedXml.GetXml();
        SetPrefix("ds", signedElement);

        XmlElement soapSignature = xmlDoc.CreateElement("soap-sec", "Signature", "http://schemas.xmlsoap.org/soap/security/2000-12");
        soapSignature.SetAttribute("xmlns:soap-sec", "http://schemas.xmlsoap.org/soap/security/2000-12");
        soapSignature.SetAttribute("SOAP-ENV:mustUnderstand", "1");

        soapSignature.AppendChild(signedElement);

        string soapNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
        XmlElement soapHeader = xmlDoc.SelectSingleNode("//SOAP-ENV:Header", GetNamespaceManager(xmlDoc, soapNamespace)) as XmlElement;
        
        if (soapHeader == null)
        {
            soapHeader = xmlDoc.CreateElement("Header", "http://schemas.xmlsoap.org/soap/envelope/");
            soapHeader.Prefix = "SOAP";
            xmlDoc.DocumentElement.InsertBefore(soapHeader, xmlDoc.DocumentElement.ChildNodes[0]);
        }
        soapHeader.AppendChild(soapSignature);
        return xmlDoc.OuterXml;
    }

I need XML signature as follows, So I have to add "ds" to all the child elements of the signature element. SetPrefix("ds", signedElement) will add the prefix "ds". Does it error-prone to add prefix after calling signedXml.ComputeSignature();

Expected Signature

<soap-sec:Signature xmlns:soap-sec="http://schemas.xmlsoap.org/soap/security/2000-12" mustUnderstand="1">
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
            <ds:Reference URI="#Body">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <ds:DigestValue>..</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>XrBHe3hAO</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509IssuerSerial>
                    <ds:X509IssuerName>...</ds:X509IssuerName>
                    <ds:X509SerialNumber>..</ds:X509SerialNumber>
                </ds:X509IssuerSerial>
                <ds:X509Certificate>....</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
</soap-sec:Signature>
0

There are 0 answers