PageRenderTime 25ms CodeModel.GetById 16ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CSXmlDigitalSignature/MainForm.cs

#
C# | 261 lines | 141 code | 44 blank | 76 comment | 13 complexity | cec18d741e9bc04f1f39e0137d510ab4 MD5 | raw file
  1/******************************** Module Header ********************************\
  2* Module Name:  MainForm.cs
  3* Project:      CSXmlDigitalSignature
  4* Copyright (c) Microsoft Corporation.
  5* 
  6* You can use the classes in the System.Security.Cryptography.Xml namespace to
  7* sign an XML document or part of an XML document with a digital signature. 
  8* XML digital signatures (XMLDSIG) allow you to verify that data was not 
  9* altered after it was signed. For more information about the XMLDSIG standard
 10* see the World Wide Web Consortium (W3C) specification at 
 11* http://www.w3.org/TR/xmldsig-core/. 
 12*
 13* The code example in this procedure demonstrates how to digitally sign an 
 14* entire XML document and attach the signature to the document in a 
 15* <Signature> element. The example creates an RSA signing key, adds the key
 16* to a secure key container, and then uses the key to digitally sign an XML 
 17* document. The key can then be retrieved to verify the XML digital signature,
 18* or be used to sign another XML document.
 19* 
 20* Code Logic:
 21* 1 Create Xml document 
 22* 2 Click Sign button to sign one Xml document
 23* 2.1 Create one RSACryptoServiceProvider object for signing
 24* 2.2 Creaet one SignedXml object to facilitate creating XML signatures
 25* 2.3 Append the element to the XML document
 26* 2.4 Save Xml document to file
 27* 3 Click Verify button to verify Xml document
 28* 3.1 Create one RSACryptoServiceProvider object to verify digital signature
 29* 3.2 Creaet one SignedXml object to verify digital signature
 30* 4 Modify Xml Document. Then verify the XmlDocument to know its correctness
 31* 
 32* This source is subject to the Microsoft Public License.
 33* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
 34* All other rights reserved.
 35* 
 36* History:
 37* * 4/14/2009 12:00 AM Riquel Dong Created
 38\*******************************************************************************/
 39
 40#region Using Directives
 41using System;
 42using System.Collections.Generic;
 43using System.ComponentModel;
 44using System.Data;
 45using System.Drawing;
 46using System.Linq;
 47using System.Text;
 48using System.Windows.Forms;
 49using System.Xml.Linq;
 50using System.Xml;
 51using System.Security.Cryptography;
 52using System.Security.Cryptography.Xml;
 53#endregion
 54
 55
 56namespace CSXmlDigitalSignature
 57{
 58    public partial class MainForm : Form
 59    {
 60        private XmlDocument xmlDoc;
 61
 62        public MainForm()
 63        {
 64            InitializeComponent();
 65        }
 66
 67        private void XMLDigitalSignatureForm_Load(object sender, EventArgs e)
 68        {
 69            GenerateXmlDocument();
 70            tbxPlaintext.Text = xmlDoc.OuterXml;
 71        }
 72
 73        private void GenerateXmlDocument()
 74        {
 75            XDocument xdoc = new XDocument(
 76                new XDeclaration("1.0", "utf-8", "yes"),
 77                new XComment("This is a comment"),
 78                new XElement("invoice",
 79                    new XElement("items",
 80                        new XElement("item",
 81                            new XElement("desc", ""),
 82                            new XElement("unitprice", "14.95"),
 83                            new XElement("quantity", "1")),
 84                            new XElement("creditcard",
 85                                new XElement("number", "19834209"),
 86                                new XElement("expiry", "02/02/2002")
 87                                ))));
 88            xdoc.Save("test.xml");
 89            xmlDoc = new XmlDocument();
 90            xmlDoc.Load("test.xml");
 91        }
 92
 93        // Save public key to verify digital signature
 94        private String publicOnlyKey;
 95        private void btnSign_Click(object sender, EventArgs e)
 96        {
 97            try
 98            {
 99                /////////////////////////////////////////////////////////////////
100                // Create a new RSA signing key and export public key for 
101                // verification.
102
103                RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
104                publicOnlyKey = rsaKey.ToXmlString(false);
105                tbxRSAParameters.Text = publicOnlyKey;
106
107
108                /////////////////////////////////////////////////////////////////
109                // Sign the XML document.
110                // 
111
112                SignXml(xmlDoc, rsaKey);
113                MessageBox.Show("XML file signed.");
114
115
116                /////////////////////////////////////////////////////////////////
117                // Save and display the signed document.
118                // 
119
120                xmlDoc.Save("test1.xml");
121                tbxDigitalSignature.Text = xmlDoc.OuterXml;
122            }
123            catch (Exception ex)
124            {
125                Console.WriteLine(ex.Message);
126            }
127        }
128
129        public static void SignXml(XmlDocument Doc, RSA Key)
130        {
131            // Check arguments.
132            if (Doc == null)
133                throw new ArgumentException("Doc");
134            if (Key == null)
135                throw new ArgumentException("Key");
136
137            try
138            {
139                // Create a SignedXml object to generate signature.
140                SignedXml signedXml = new SignedXml(Doc);
141
142                // Add the key to the SignedXml document
143                signedXml.SigningKey = Key;
144
145                // Create a reference to be signed
146                Reference reference = new Reference();
147                reference.Uri = "";
148
149                // Add an enveloped transformation to the reference
150                XmlDsigEnvelopedSignatureTransform env =
151                    new XmlDsigEnvelopedSignatureTransform();
152                reference.AddTransform(env);
153
154                // Add the reference to the SignedXml object
155                signedXml.AddReference(reference);
156
157                // Compute the signature
158                signedXml.ComputeSignature();
159
160                // Get the XML representation of the signature and save
161                // it to an XmlElement object.
162                XmlElement xmlDigitalSignature = signedXml.GetXml();
163
164                // Append the element to the XML document.
165                Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
166            }
167            catch (Exception ex)
168            {
169                MessageBox.Show(ex.Message);
170            }
171        }
172
173        private void btnVerify_Click(object sender, EventArgs e)
174        {
175            /////////////////////////////////////////////////////////////////////
176            // Create a new RSA signing key and import public key for 
177            // verification.
178            //
179
180            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
181            rsaKey.FromXmlString(publicOnlyKey);
182
183
184            /////////////////////////////////////////////////////////////////////
185            // Load the signed XML, and call VerifyXml to verify the signature of 
186            // the signed XML.
187            // 
188
189            XmlDocument xmlDoc = new XmlDocument();
190            xmlDoc.Load("test1.xml");
191
192            bool result = VerifyXml(xmlDoc, rsaKey);
193
194            if (result)
195            {
196                MessageBox.Show("The XML signature is valid.");
197            }
198            else
199            {
200                MessageBox.Show("The XML signature is not valid.");
201            }
202        }
203
204        public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
205        {
206            // Check arguments.
207            if (Doc == null)
208                throw new ArgumentException("Doc");
209            if (Key == null)
210                throw new ArgumentException("Key");
211
212
213            /////////////////////////////////////////////////////////////////////
214            // Create a SignedXml object to verify the signature
215            //
216
217            SignedXml signedXml = new SignedXml(Doc);
218
219            // Find Signature node and create a new XmlNodeList object
220            XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
221
222            // Throw an exception if no signature was found.
223            if (nodeList.Count <= 0)
224            {
225                throw new CryptographicException(
226                    "Verification failed:" +
227                    " No Signature was found in the document.");
228            }
229
230            // This example only supports one signature for entire XML document
231            if (nodeList.Count >= 2)
232            {
233                throw new CryptographicException(
234                    "Verification failed: More that one signature was found.");
235            }
236
237            // Load the first <signature> node.  
238            signedXml.LoadXml((XmlElement)nodeList[0]);
239
240            // Check the signature and return the result.
241            return signedXml.CheckSignature(Key);
242        }
243
244        private void btnChangeXML_Click(object sender, EventArgs e)
245        {
246            // Modify the value of the Xml document for test. 
247
248            XDocument xDoc = XDocument.Load("test1.xml");
249
250            if (xDoc != null)
251            {
252                xDoc.Element("invoice").Element("items").
253                    Element("creditcard").Element("number").SetValue("19834210");
254
255                xDoc.Save("test1.xml");
256
257                tbxModifiedMessage.Text = xDoc.ToString();
258            }
259        }
260    }
261}