AttriShivi
AttriShivi

Reputation: 11

Generating XML file with a Digital Signature Certificate

I am trying to sign an XML file in C# .NET 4.0 with a private RSA Key generated by OpenSSL. My source code looks like :

    public static void SignXml(String filePath, String certificatePath)
    {
        CspParameters cspParams1 = new CspParameters();
        cspParams1.KeyContainerName = certificatePath;
        RSACryptoServiceProvider rsakey = new RSACryptoServiceProvider(cspParams1);


        XmlDocument xmlDoc = new XmlDocument();

        // Load an XML file into the XmlDocument object.
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.Load(filePath);
        SignedXml signedXml = new SignedXml();
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = certificatePath;

        // Create a new RSA signing key and save it in the container. 
        RSACryptoServiceProvider Key = new RSACryptoServiceProvider(cspParams);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

        reference.AddTransform(env);

        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);
        KeyInfo keyInfo = new KeyInfo();

        // Load the X509 certificate.


        X509Certificate MSCert = X509Certificate.CreateFromCertFile(certificatePath);


        // Load the certificate into a KeyInfoX509Data object 
        // and add it to the KeyInfo object.
        keyInfo.AddClause(new KeyInfoX509Data(MSCert));
        keyInfo.AddClause(new RSAKeyValue((RSA)Key));

        // Add the KeyInfo object to the SignedXml object.
        signedXml.KeyInfo = keyInfo;
        // Compute the signature.
        signedXml.ComputeSignature();

        // Get the XML representation of the signature and save 
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));


        xmlDoc.Save(filePath);
    }

I am calling the class (CPSMSXmlGenerator) in my application as a DLL(named DBTBeneficiariesCPSMS) and code for calling it is :

  Dim genXml As String = DBTBeneficiariesCPSMS.CPSMSXmlGenerator.getXmlFile1(xml)

        'Dim appPath As String = Request.PhysicalApplicationPath
        Dim fullPath As String = Server.MapPath("/XML/") + dataSource + ".xml"
        lblMessage.Text = fullPath
        Dim SwFromFile As StreamWriter = New StreamWriter(fullPath)
        SwFromFile.Write(genXml)
        SwFromFile.Flush()
        SwFromFile.Close()

        CPSMSXmlGenerator.SignXml(fullPath, Server.MapPath("/XML/aua.cer"))

Now, the problem is whenever my application runs, it halts at ' Reference.Uri="" ' and an error as :- Error: An XmlDocument context is required to resolve the Reference Uri .

is displayed, and XML file without digital signature certificate generates.

Upvotes: 1

Views: 4132

Answers (1)

subup
subup

Reputation: 31

xmDoc is not passsed to SignedXml. Passing that as param should fix the problem

SignedXml signedXml = new SignedXml(xmlDoc); 

Upvotes: 2

Related Questions