PageRenderTime 160ms CodeModel.GetById 21ms RepoModel.GetById 0ms 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. #region Using Directives
  40. using System;
  41. using System.Collections.Generic;
  42. using System.ComponentModel;
  43. using System.Data;
  44. using System.Drawing;
  45. using System.Linq;
  46. using System.Text;
  47. using System.Windows.Forms;
  48. using System.Xml.Linq;
  49. using System.Xml;
  50. using System.Security.Cryptography;
  51. using System.Security.Cryptography.Xml;
  52. #endregion
  53. namespace CSXmlDigitalSignature
  54. {
  55. public partial class MainForm : Form
  56. {
  57. private XmlDocument xmlDoc;
  58. public MainForm()
  59. {
  60. InitializeComponent();
  61. }
  62. private void XMLDigitalSignatureForm_Load(object sender, EventArgs e)
  63. {
  64. GenerateXmlDocument();
  65. tbxPlaintext.Text = xmlDoc.OuterXml;
  66. }
  67. private void GenerateXmlDocument()
  68. {
  69. XDocument xdoc = new XDocument(
  70. new XDeclaration("1.0", "utf-8", "yes"),
  71. new XComment("This is a comment"),
  72. new XElement("invoice",
  73. new XElement("items",
  74. new XElement("item",
  75. new XElement("desc", ""),
  76. new XElement("unitprice", "14.95"),
  77. new XElement("quantity", "1")),
  78. new XElement("creditcard",
  79. new XElement("number", "19834209"),
  80. new XElement("expiry", "02/02/2002")
  81. ))));
  82. xdoc.Save("test.xml");
  83. xmlDoc = new XmlDocument();
  84. xmlDoc.Load("test.xml");
  85. }
  86. // Save public key to verify digital signature
  87. private String publicOnlyKey;
  88. private void btnSign_Click(object sender, EventArgs e)
  89. {
  90. try
  91. {
  92. /////////////////////////////////////////////////////////////////
  93. // Create a new RSA signing key and export public key for
  94. // verification.
  95. RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
  96. publicOnlyKey = rsaKey.ToXmlString(false);
  97. tbxRSAParameters.Text = publicOnlyKey;
  98. /////////////////////////////////////////////////////////////////
  99. // Sign the XML document.
  100. //
  101. SignXml(xmlDoc, rsaKey);
  102. MessageBox.Show("XML file signed.");
  103. /////////////////////////////////////////////////////////////////
  104. // Save and display the signed document.
  105. //
  106. xmlDoc.Save("test1.xml");
  107. tbxDigitalSignature.Text = xmlDoc.OuterXml;
  108. }
  109. catch (Exception ex)
  110. {
  111. Console.WriteLine(ex.Message);
  112. }
  113. }
  114. public static void SignXml(XmlDocument Doc, RSA Key)
  115. {
  116. // Check arguments.
  117. if (Doc == null)
  118. throw new ArgumentException("Doc");
  119. if (Key == null)
  120. throw new ArgumentException("Key");
  121. try
  122. {
  123. // Create a SignedXml object to generate signature.
  124. SignedXml signedXml = new SignedXml(Doc);
  125. // Add the key to the SignedXml document
  126. signedXml.SigningKey = Key;
  127. // Create a reference to be signed
  128. Reference reference = new Reference();
  129. reference.Uri = "";
  130. // Add an enveloped transformation to the reference
  131. XmlDsigEnvelopedSignatureTransform env =
  132. new XmlDsigEnvelopedSignatureTransform();
  133. reference.AddTransform(env);
  134. // Add the reference to the SignedXml object
  135. signedXml.AddReference(reference);
  136. // Compute the signature
  137. signedXml.ComputeSignature();
  138. // Get the XML representation of the signature and save
  139. // it to an XmlElement object.
  140. XmlElement xmlDigitalSignature = signedXml.GetXml();
  141. // Append the element to the XML document.
  142. Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
  143. }
  144. catch (Exception ex)
  145. {
  146. MessageBox.Show(ex.Message);
  147. }
  148. }
  149. private void btnVerify_Click(object sender, EventArgs e)
  150. {
  151. /////////////////////////////////////////////////////////////////////
  152. // Create a new RSA signing key and import public key for
  153. // verification.
  154. //
  155. RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
  156. rsaKey.FromXmlString(publicOnlyKey);
  157. /////////////////////////////////////////////////////////////////////
  158. // Load the signed XML, and call VerifyXml to verify the signature of
  159. // the signed XML.
  160. //
  161. XmlDocument xmlDoc = new XmlDocument();
  162. xmlDoc.Load("test1.xml");
  163. bool result = VerifyXml(xmlDoc, rsaKey);
  164. if (result)
  165. {
  166. MessageBox.Show("The XML signature is valid.");
  167. }
  168. else
  169. {
  170. MessageBox.Show("The XML signature is not valid.");
  171. }
  172. }
  173. public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
  174. {
  175. // Check arguments.
  176. if (Doc == null)
  177. throw new ArgumentException("Doc");
  178. if (Key == null)
  179. throw new ArgumentException("Key");
  180. /////////////////////////////////////////////////////////////////////
  181. // Create a SignedXml object to verify the signature
  182. //
  183. SignedXml signedXml = new SignedXml(Doc);
  184. // Find Signature node and create a new XmlNodeList object
  185. XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
  186. // Throw an exception if no signature was found.
  187. if (nodeList.Count <= 0)
  188. {
  189. throw new CryptographicException(
  190. "Verification failed:" +
  191. " No Signature was found in the document.");
  192. }
  193. // This example only supports one signature for entire XML document
  194. if (nodeList.Count >= 2)
  195. {
  196. throw new CryptographicException(
  197. "Verification failed: More that one signature was found.");
  198. }
  199. // Load the first <signature> node.
  200. signedXml.LoadXml((XmlElement)nodeList[0]);
  201. // Check the signature and return the result.
  202. return signedXml.CheckSignature(Key);
  203. }
  204. private void btnChangeXML_Click(object sender, EventArgs e)
  205. {
  206. // Modify the value of the Xml document for test.
  207. XDocument xDoc = XDocument.Load("test1.xml");
  208. if (xDoc != null)
  209. {
  210. xDoc.Element("invoice").Element("items").
  211. Element("creditcard").Element("number").SetValue("19834210");
  212. xDoc.Save("test1.xml");
  213. tbxModifiedMessage.Text = xDoc.ToString();
  214. }
  215. }
  216. }
  217. }