Click here to Skip to main content
12,348,852 members (60,795 online)
Rate this:
 
Please Sign up or sign in to vote.
See more: C# Visual-Studio VS2010 , +
I am having a problem parsing out this xml file using XmlElement, the proposed solutions online suggests work-arounds by referencing SAML methods but that does not work for my xml. Any ideas on how to get the XmlElement of SignatureValue? current error is "Malformed element Signature" at line: "signedXml.LoadXml((XmlElement)nodeList[0]);". And below is a piece of the xml used for this test - with the signature and digest values removed. My thought here is that the xml is not being parsed properly by the XmlElement/nodeList:

<Message xmlns="http://www.blah.com/messaging" version="010" release="006">
   <Header>
      <To Qualifier="blah"</To>
      <From Qualifier="blah"</From>
      <MessageID>93585dc9571b49fda</MessageID>
      <SentTime>2013-08-26T17:27:43.80Z</SentTime>
      <SenderSoftware>
         <SenderSoftwareDeveloper>blahpts</SenderSoftwareDeveloper>
         <SenderSoftwareProduct>Certification Testing</SenderSoftwareProduct>
         <SenderSoftwareVersionRelease>2013</SenderSoftwareVersionRelease>
      </SenderSoftware>
      <PrescriberOrderNumber>blah 2.1 ES</PrescriberOrderNumber>
      <DigitalSignature version="2.0">
         <DigestValue>jblahlwT1Y=</DigestValue>
         <SignatureValue>blahblah</SignatureValue>
         <X509Data>blahblahblah</X509Data>
      </DigitalSignature>
   </Header>
   <Body>


public static void Main(String[] args)
{
    try
    {
        // Create a new CspParameters object to specify
        // a key container.
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
 
        // Create a new RSA signing key and save it in the container.
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
 
        // Create a new XML document.
        XmlDocument xmlDoc = new XmlDocument();
 
        // Load an XML file into the XmlDocument object.
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.Load(args[0]); //("test.xml");

        // Verify the signature of the signed XML.
        Console.WriteLine("Verifying signature...");
        bool result = VerifyXml(xmlDoc, rsaKey);
 
        // Display the results of the signature verification to
        // the console.
        if (result)
        {
            Console.WriteLine("The XML signature is valid.");
        }
        else
        {
            Console.WriteLine("The XML signature is not valid.");
        }
 
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}
 

 

// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
    // Check arguments.
    if (Doc == null)
        throw new ArgumentException("Doc");
    if (Key == null)
        throw new ArgumentException("Key");
 
    // Create a new SignedXml object and pass it
    // the XML document class.
    SignedXml signedXml = new SignedXml(Doc);
 
    // Find the "Signature" node and create a new
    // XmlNodeList object.
    XmlNodeList nodeList = Doc.GetElementsByTagName("SignatureValue");
 

    // Throw an exception if no signature was found.
    if (nodeList.Count <= 0)
    {
        throw new CryptographicException("Verification failed: No Signature was found in the document.");
    }
 
    // This example only supports one signature for
    // the entire XML document.  Throw an exception
    // if more than one signature was found.
    if (nodeList.Count >= 2)
    {
        throw new CryptographicException("Verification failed: More that one signature was found for the document.");
    }
 
    //
    // Load the first <signature> node.
    signedXml.LoadXml((XmlElement)nodeList[0]); //

    // Check the signature and return the result.
    return signedXml.CheckSignature(Key);
}

What will make it easier is the following specifications:

1) Calculate the Digest Value of the Plain Text, the plain text is the concatinated value of all fields/values in given xml. This process includes using SHA-1 hash to reduce the ASCII encoded plain text to a unique Digest Value.
2) Decrypt the Signature Value, impotant to mention that the encrypted version of the hash of the signed information. The hash value is also the Digest Value. The sender's private key is what was used to encrypt the digest to create the Signature Value. Signature Value can only be decrypted with the sender's public key which is contained in the digital certificate in the X509Data element.
3) Compare the Digest Value that my code calcualtes to match the Digest Value mentioned in the xml from the decrypted signature if the signature is valid.
4) validating the certificate is required, and a message should only be accepted as valid if it has been signed and verified with a valid digital certificate.
Posted 23-Aug-13 7:34am
Edited 3-Sep-13 10:58am
v20
Comments
PIEBALDconsult 23-Aug-13 13:54pm
   
Which line is throwing the Exception?
ProgrammerX1 23-Aug-13 15:19pm
   
I noticed that I missed few more lines of the code, I just added them...
Richard MacCutchan 24-Aug-13 4:43am
   
Where is that line in the above code?
ProgrammerX1 24-Aug-13 23:53pm
   
Sorry about that, here it is: rsa.Decrypt(RSAKeyInfo.Modulus,false);
Richard MacCutchan 25-Aug-13 3:08am
   
Well that's two different lines, neither of which appears in your original question. I suggest you use your debugger to diagnose why it cannot find the key, in whichever of these lines the program actually uses.
ProgrammerX1 25-Aug-13 21:36pm
   
I have updated the code to reflect this line. I think I am doing the wrong thing here, attempting to decrypt the public key, rather I need to decrypt the Signed Value againest the public key, therefore how can I decrypt the signed value using the public key?
Richard MacCutchan 26-Aug-13 2:33am
   
I still can't see exactly what you are trying to do, but I would suggest spendi ng some time reading the documentation.
ProgrammerX1 27-Aug-13 19:34pm
   
Hello Richard, I've added my specs at the bottom of the code, I did figure out most of the items except for item 2 and the last part of item 4 (in bold), I wonder if you can provide some assistance here. Thank you.
Richard MacCutchan 28-Aug-13 2:50am
   
Sorry, but that is a bit beyond what can be answered in a forum like this. There are various samples and articles on encryption to be found, I would suggest working through some of them to get a fuller understanding of what you need to do.
ProgrammerX1 28-Aug-13 19:26pm
   
Code update but having a new error, any ideas?
Richard MacCutchan 29-Aug-13 3:18am
   
Yes, read the documentation and use your debugger.

It's almost impossible to guess what may be happening with your code without actually running it and seeing the values of the various objects and variables when the errors occur.
ProgrammerX1 29-Aug-13 14:10pm
   
Thanks for your notes Richard, I have troubleshot the issue, it is down to the format of the xml, it is an issue when it comes to getting that Signature value, so I am hoping someone can point out exactly what is the issue with the xml format.
Richard MacCutchan 30-Aug-13 2:46am
   
The To and From elements are malformed. The attribute values are missing quote characters, and should be <To qualifier="blah"></To>
<From qualifier="blah"></From>
.
ProgrammerX1 30-Aug-13 12:02pm
   
Thank you for the note Richard, this was just a bad copy and paste/formatting on this site, the actual xml have those quotes, I went ahead and corrected the example. Any other ideas?
Richard MacCutchan 30-Aug-13 12:11pm
   
Sorry no, and you still have malformed XML in your question.

1 solution

Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Your question's XML is malformed. You need to fix your XML.
These lines are malformed...
<To Qualifier="blah"</To>
<From Qualifier="blah"</From>
The above should probably be...
<To Qualifier="blah"></To>
<From Qualifier="blah"></From>
These lines are malformed too...
<SignatureValue>blahblah>
<X509Data>blahblahblah;/X509Data>
... and I'm guessing this is what you want for them...
<SignatureValue>blahblah</SignatureValue>
<X509Data>blahblahblah;</X509Data>
  Permalink  
v2
Comments
ProgrammerX1 3-Sep-13 17:01pm
   
Thank you for the comments, it is not really the reason, those items you point out were self inflected (such as blah...) and some are related to copy and paste...
I believe the issue is bigger than that, I am guessing the tag name "Header" or "Message" might be throwing it off, the thing here is that I have no way of changing the xml, it is as is (as received from the vendor), what I am really after here is to see of to make signedXml.LoadXml to work properly in loading this xml....
idenizeni 3-Sep-13 17:27pm
   
No offense, but there is no point in trying to help if we can't trust the code you posted.

The error you receive, 'Malformed element Signature' is saying your XML is not well formed at the element Signature. I don't even see the Signature element in your XML.
ProgrammerX1 3-Sep-13 17:31pm
   
I had to manually modify the xml before posting it on this site because it contains information that can't be shared, hence when publishing it online I had to modify few elements.

As far as your second comment, you are right, that is the issue, and that is why since the xml starts with
idenizeni 3-Sep-13 17:42pm
   
You could try posting dummy but complete XML that doesn't contain sensitive information. Since the error is related to malformed XML and the XML you posted doesn't contain the complete XML structure (regardless of the details) we can only make guesses. I will say that you should look at the content of your XML, if it contains any of the XML special characters in the node values then you may need to ensure the XML in properly encoded when written. See this link for more information on XML special characters...

http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
ProgrammerX1 5-Sep-13 12:43pm
   
Here is where the problem takes place: // Load the first node. signedXml.LoadXml((XmlElement)nodeList[0]); When attempting to load the node list, it seems that the method "LoadXml" expects the element name "Signature" this is based on the fact that the signed XML is supposed to have that element in the xml so that LoadXml can find it, but not all xmls are the same, in my case the xml starts with the element "Message" (see xml posted on top). So the question here how can I load this xml with the first element being Message? Is there an override method that can be written or maybe a different way of doing things such as taking the current xml and create a small xml in memory with the right starting element name of "Signature" then process that instead of the original xml, or even renaming the current parent element "Message" to "Signature" keeping in mind that there the "Header" element that it may need to go... thinking upload...
nileshinfotech84 18-Feb-14 11:16am
   
Have you found solution to this problem?

Actually I am having a similar issue and getting same message "Malformed element Signature"

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web02 | 2.8.160621.1 | Last Updated 3 Sep 2013
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100