잊지 않겠습니다.

RSAServiceProvider를 이용해서 xml 파일에 서명 및 Decryption 하는 과정
RSAServiceProvider를 제공된 public key를 이용해서 얻어내는 것이 이 코드의 핵심.



private String publicOnlyKey;
private void btnSign_Click(object sender, EventArgs e)
{
    try
    {
        /////////////////////////////////////////////////////////////////
        // Create a new RSA signing key and export public key for 
        // verification.
        
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
        
        //Public Key exported
        //Public Key 뿐 아니라 Private Key도 얻어내는 것이 가능하다. 사용자에게 Key를 보내거나 저장할 때 이용 가능
        publicOnlyKey = rsaKey.ToXmlString(false);
        tbxRSAParameters.Text = publicOnlyKey;
        
        /////////////////////////////////////////////////////////////////
        // Sign the XML document.
        // 

        SignXml(xmlDoc, rsaKey);
        MessageBox.Show("XML file signed.");


        /////////////////////////////////////////////////////////////////
        // Save and display the signed document.
        // 

        xmlDoc.Save("test1.xml");
        tbxDigitalSignature.Text = xmlDoc.OuterXml;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

///XML파일을 RSA를 이용해서 서명. SignedXml class가 있는 것을 기억하고 있을것!
public static void SignXml(XmlDocument Doc, RSA Key)
{
    // Check arguments.
    if (Doc == null)
        throw new ArgumentException("Doc");
    if (Key == null)
        throw new ArgumentException("Key");

    try
    {
        // Create a SignedXml object to generate signature.
        SignedXml signedXml = new SignedXml(Doc);

        // 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);

        // 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.
        Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

private void btnVerify_Click(object sender, EventArgs e)
{
    /////////////////////////////////////////////////////////////////////
    // Create a new RSA signing key and import public key for 
    // verification.
    //

    //NOTE:Public RSA Key를 이용해서 RSACryptoService Generate
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
    rsaKey.FromXmlString(publicOnlyKey);
    /////////////////////////////////////////////////////////////////////
    // Load the signed XML, and call VerifyXml to verify the signature of 
    // the signed XML.
    // 

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load("test1.xml");

    bool result = VerifyXml(xmlDoc, rsaKey);

    if (result)
    {
        MessageBox.Show("The XML signature is valid.");
    }
    else
    {
        MessageBox.Show("The XML signature is not valid.");
    }
}

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 SignedXml object to verify the signature
    //

    SignedXml signedXml = new SignedXml(Doc);

    // Find Signature node and create a new XmlNodeList object
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

    // 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 entire XML document
    if (nodeList.Count >= 2)
    {
        throw new CryptographicException(
            "Verification failed: More that one signature was found.");
    }

    // Load the first  node.  
    signedXml.LoadXml((XmlElement)nodeList[0]);

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

private void btnChangeXML_Click(object sender, EventArgs e)
{
    // Modify the value of the Xml document for test. 

    XDocument xDoc = XDocument.Load("test1.xml");

    if (xDoc != null)
    {
        xDoc.Element("invoice").Element("items").
            Element("creditcard").Element("number").SetValue("19834210");

        xDoc.Save("test1.xml");

        tbxModifiedMessage.Text = xDoc.ToString();
    }
}
Posted by Y2K
,

0004. XmlGeneral

Sample Codes 2010. 1. 5. 13:21
xml파일을 각 ElementNode별로 읽고, XmlDocument를 생성하고 저장하는 sample code
XmlDocument에 새로운 Element를 생성하는 것은 생성후에 XmlDocument에 넣는 것이 아니라, XmlDocument를 통해 객체를
생성하고, 생성된 객체에 값을 넣은 이후에 XmlDocument에 Append하는 과정을 거쳐야지 된다는 것을 기억하면 매우 쉬운 소스다.


/****************************** Module Header ******************************\
* Module Name:	Program.cs
* Project:		CSXmlGeneral
* Copyright (c) Microsoft Corporation.
* 
* This C# sample project shows how to read a XML file by using XmlTextReader 
* or XmlNodeReader. It also shows, instead of using forward-only reader, how 
* to read, modify, and update Xml element using the XmlDocument class. This 
* class will load the whole document into memory for modification and we can 
* save the modified XML file to the file system.
* 
* The XML file used by the demo has this format:
* 
* 
*  
*    Gambardella, Matthew
*    XML Developer's Guide
*    Computer
*    44.95
*    2000-10-01
*    
*      An in-depth look at creating applications
*      with XML.
*    
*  
*  
*   ...
*  
* 
* 
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
* All other rights reserved.
* 
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

#region Using directives
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
#endregion


class Program
{
    static void Main(string[] args)
    {
        /////////////////////////////////////////////////////////////////////
        // Read XML document using the XmlTextReader class.
        // 

        // The XmlTextReader acts as a reader pointer that only moves forward.
        // Because it always moves forward and read a piece of data into 
        // memory buffer, it has better performance than the XmlDocument 
        // class which loads the whole document into memory.

        Console.WriteLine("Loading XML using XmlTextReader...");

        XmlTextReader xmlTextReader = new XmlTextReader(@"Books.xml");
        xmlTextReader.WhitespaceHandling = WhitespaceHandling.None;

        while (xmlTextReader.Read())
        {
            if (xmlTextReader.Name == "book")
            {
                Console.WriteLine(xmlTextReader.GetAttribute("id") + ": ");

                xmlTextReader.Read();
                string author = xmlTextReader.ReadElementContentAsString();
                string title = xmlTextReader.ReadElementContentAsString();
                string genre = xmlTextReader.ReadElementContentAsString();
                string price = xmlTextReader.ReadElementContentAsString();
                string publishDate = xmlTextReader.ReadElementContentAsString();
                string description = xmlTextReader.ReadElementContentAsString();

                Console.WriteLine(genre + " book \"" + title + "\" written by \"" +
                    author + "\", published on " + publishDate);
                Console.WriteLine(description);
            }
        }

        xmlTextReader.Close();


        /////////////////////////////////////////////////////////////////////
        // Read XML document using the XmlDocument and XmlNodeReader classes.
        // 

        // XmlNodeReader is similar to XmlTextReader but accepts an XmlNode 
        // instance as target to read. The following code shows how to use 
        // XmlDocument and XmlNodeReader to retrieve XML information. It is 
        // also a forward-only reader.

        Console.WriteLine("Loading XML using XmlDocument & XmlNodeReader...");

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(@"Books.xml");
        XmlNodeList xmlNodes = xmlDocument.GetElementsByTagName("book");
        foreach (XmlNode node in xmlNodes)
        {
            Console.WriteLine(node.Attributes["id"].Value + ":");

            XmlNodeReader xmlNodeReader = new XmlNodeReader(node);
            xmlNodeReader.Read();
            xmlNodeReader.Read();
            string author = xmlNodeReader.ReadElementContentAsString();
            string title = xmlNodeReader.ReadElementContentAsString();
            string genre = xmlNodeReader.ReadElementContentAsString();
            string price = xmlNodeReader.ReadElementContentAsString();
            string publishDate = xmlNodeReader.ReadElementContentAsString();
            string description = xmlNodeReader.ReadElementContentAsString();

            Console.WriteLine(genre + " book \"" + title + "\" written by \"" +
                author + "\", published on " + publishDate);
            Console.WriteLine(description);
        }


        /////////////////////////////////////////////////////////////////////
        // Make changes to the XmlDocument.
        // 

        // Modify a node value by first calling SelectSingleNode to navigate 
        // to that node and by setting its InnerText property to change its 
        // content.
        XmlNode nodeToModify = xmlDocument.DocumentElement.SelectSingleNode(
            "book/genre");
        nodeToModify.InnerText = "XML Tech";

        // Add a new XML node. In XML programming, we always call 
        // XMLDocument.Create*** to create an attribute or element. After 
        // that, we can add it into where we want by calling Node.AppendChild
        XmlElement newElement = xmlDocument.CreateElement("book");
        XmlAttribute newAttribute = xmlDocument.CreateAttribute("id");
        newAttribute.Value = "bk103";
        XmlElement authorElement = xmlDocument.CreateElement("author");
        authorElement.InnerText = "Mark Russinovich,David Solomon,Alex Ionecsu";
        XmlElement titleElement = xmlDocument.CreateElement("title");
        titleElement.InnerText = "Windows Internals, 5th edition";
        XmlElement genreElement = xmlDocument.CreateElement("genre");
        genreElement.InnerText = "Windows Server 2008";
        XmlElement priceElement = xmlDocument.CreateElement("price");
        priceElement.InnerText = "69.99";
        XmlElement publishDateElement = xmlDocument.CreateElement("publish_date");
        publishDateElement.InnerText = "2009-6-17";
        XmlElement descriptionElement = xmlDocument.CreateElement("description");
        descriptionElement.InnerText = "Windows Internals, 5th edition is the" +
            " update to Windows Internals, 4th edition to cover Windows Vista" +
            " and Windows Server 2008 (32-bit and 64-bit).";

        newElement.Attributes.Append(newAttribute);
        newElement.AppendChild(authorElement);
        newElement.AppendChild(titleElement);
        newElement.AppendChild(genreElement);
        newElement.AppendChild(priceElement);
        newElement.AppendChild(publishDateElement);
        newElement.AppendChild(descriptionElement);
        xmlDocument.DocumentElement.AppendChild(newElement);

        // Save the changes
        xmlDocument.Save("Modified Books.xml");

        // XmlLDocument does not have Close or Dispose method because it is 
        // an in-memory representation of an XML document. Once read, the 
        // file is no-longer needed.
    }
}



  
    Gambardella, Matthew
    XML Developer's Guide
    Computer
    44.95
    2000-10-01
    
      An in-depth look at creating applications
      with XML.
    
  
  
    Ralls, Kim
    Midnight Rain
    Fantasy
    5.95
    2000-12-16
    
      A former architect battles corporate zombies,
      an evil sorceress, and her own childhood to become queen
      of the world.
    
  

Posted by Y2K
,
.NET에서 Serialization은 객체를 저장하고, 객체를 다시 불러오는데 매우 유용하다. 그리고 네트워크로 Serialization된 객체를 전송하고,
다시 그 객체를 사용할 수 도 있는 .NET에서 핵심적인 기능중 하나이다.

XmlSerialization을 하기 위해 가장 유의할 점은 생성자는 input parameter가 없는 생성자만이 가능하다는 점을 항시 알아야지 된다.
input parameter가 있는 경우에는 Runtime시에 exception이 발생되게 된다.


/****************************** Module Header ******************************\
* Module Name:	Program.cs
* Project:		CSXmlSerialization
* Copyright (c) Microsoft Corporation.
* 
* This sample shows how to serialize an in-memory object to a local xml file 
* and how to deserialize the xml file back to an in-memory object using 
* C#. The designed MySerializableType includes int, string, generic, as well
* as customized type field and property.
* 
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
* All other rights reserved.
* 
* History:
* * 7/29/2009 3:00 PM Colbert Zhou Created
* * 8/20/2009 12:01 AM Jialiang Ge Reviewed
\***************************************************************************/

#region Using directives
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Collections;
#endregion


namespace CSXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            /////////////////////////////////////////////////////////////////
            // Serialize the object to an XML file.
            // 

            // Create and initialize a MySerializableType instance.
            MySerializableType instance = new MySerializableType();
            instance.BoolValue = true;
            instance.IntValue = 1;
            instance.StringValue = "Test String";
            instance.ListValue.Add("List Item 1");
            instance.ListValue.Add("List Item 2");
            instance.ListValue.Add("List Item 3");
            instance.AnotherTypeValue = new AnotherType();
            instance.AnotherTypeValue.IntValue = 2;
            instance.AnotherTypeValue.StringValue = "Inner Test String";

            // Create the serializer
            XmlSerializer serializer = new XmlSerializer(typeof(MySerializableType));

            // Serialize the object to an XML file
            using (StreamWriter streamWriter = File.CreateText(
                "CSXmlSerialization.xml"))
            {
                serializer.Serialize(streamWriter, instance);
            }


            /////////////////////////////////////////////////////////////////
            // Deserialize from a XML file to an object instance.
            // 

            // Deserialize the object
            MySerializableType deserializedInstance;
            using (StreamReader streamReader = File.OpenText(
                "CSXmlSerialization.xml"))
            {
                deserializedInstance = serializer.Deserialize(streamReader) 
                    as MySerializableType;
            }

            // Dump the object
            Console.WriteLine("BoolValue: {0}", deserializedInstance.BoolValue);
            Console.WriteLine("IntValue: {0}", deserializedInstance.IntValue);
            Console.WriteLine("StringValue: {0}", deserializedInstance.StringValue);
            Console.WriteLine("AnotherTypeValue.IntValue: {0}", 
                deserializedInstance.AnotherTypeValue.IntValue);
            Console.WriteLine("AnotherTypeValue.StringValue: {0}", 
                deserializedInstance.AnotherTypeValue.StringValue);
            Console.WriteLine("ListValue: ");
            foreach (object obj in deserializedInstance.ListValue)
            {
                Console.WriteLine(obj.ToString());
            }
        }
    }


    /// 
    /// Serializable Type Declaration
    /// 
    [Serializable()]
    public class MySerializableType
    {
        // String field and property
        private string stringValue;
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }

        // Bool field and property
        private bool boolValue;
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        // Int field and property
        private int intValue;
        public int IntValue
        {
            get { return intValue; }
            set { intValue = value; }
        }

        // Another type field and property
        private AnotherType anotherTypeValue;
        public AnotherType AnotherTypeValue
        {
            get { return anotherTypeValue; }
            set { anotherTypeValue = value; }
        }

        // Generic type field and property
        private List listValue = new List();
        public List ListValue
        {
            get { return listValue; }
            set { listValue = value; }
        }

        // Ignore a field using NonSerialized attribute
        [NonSerialized()]
        private int ignoredField = 1;
    }

    /// 
    /// Another Type Declaration
    /// 
    [Serializable()]
    public class AnotherType
    {
        private string stringValue;
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }

        private int intValue;
        public int IntValue
        {
            get { return intValue; }
            set { intValue = value; }
        }
    }
}
Posted by Y2K
,