PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Visual Studio 2008/CSXmlEncryption/MainForm.cs

#
C# | 327 lines | 176 code | 44 blank | 107 comment | 20 complexity | eebeeb08beba85a29fcbc5c740900af4 MD5 | raw file
  1. /****************************** Module Header ******************************\
  2. * Module Name: MainForm.cs
  3. * Project: CSXmlEncryption
  4. * Copyright (c) Microsoft Corporation.
  5. *
  6. * CSXmlEncryption demonstrates how to use .NET built-in classes to encrypt
  7. * and decrypt Xml document:
  8. *
  9. * Use .NET built-in classes to encrypt and decrypt Xml document.
  10. *
  11. * A. Creates a cryptographic provider object which supplies public/private
  12. * key pair.
  13. * B. Creates a separate session key using symmetric algorithm.
  14. * C. Uses the session key to encrypt the XML document and then uses public
  15. * key of stepA f to encrypt the session key.
  16. * D. Saves the encrypted AES session key and the encrypted XML data to the
  17. * XML document within a new <EncryptedData> element.
  18. * E. To decrypt the XML element, we retrieve the private key of stepA, use
  19. * it to decrypt the session key, and then use the session key to decrypt
  20. * the document.
  21. *
  22. * This source is subject to the Microsoft Public License.
  23. * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  24. * All other rights reserved.
  25. *
  26. * History:
  27. * * 4/14/2009 12:00 AM Riquel Dong Created
  28. \***************************************************************************/
  29. #region Using Directives
  30. using System;
  31. using System.Collections.Generic;
  32. using System.ComponentModel;
  33. using System.Data;
  34. using System.Drawing;
  35. using System.Linq;
  36. using System.Text;
  37. using System.Windows.Forms;
  38. using System.Xml.Linq;
  39. using System.Xml;
  40. using System.Security.Cryptography;
  41. using System.Security.Cryptography.Xml;
  42. #endregion
  43. namespace CSXmlEncryption
  44. {
  45. public partial class MainForm : Form
  46. {
  47. // XmlDocument object for encryption and decryption
  48. private XmlDocument xmlDoc;
  49. public MainForm()
  50. {
  51. InitializeComponent();
  52. }
  53. private void btnEncrypt_Click(object sender, EventArgs e)
  54. {
  55. /////////////////////////////////////////////////////////////////////
  56. // Create a new RSA key and save it in the container.
  57. // This key will encrypt a symmetric key, which
  58. // Will then be encryped in the XML document
  59. //
  60. CspParameters cspParams = new CspParameters();
  61. cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
  62. RSACryptoServiceProvider rsaKey =
  63. new RSACryptoServiceProvider(cspParams);
  64. this.tbxRSAParameters.Text = rsaKey.ToXmlString(true);
  65. try
  66. {
  67. /////////////////////////////////////////////////////////////////
  68. // Call Encrypt subroutine to encrypt the "creditcard" element
  69. //
  70. Encrypt(xmlDoc, "creditcard", "EncryptedElement1", rsaKey, "rsaKey");
  71. // Save the XML document.
  72. xmlDoc.Save("test.xml");
  73. // Display message of "Encrypted XML" to user
  74. MessageBox.Show("Encrypted XML");
  75. tbxCipherTextasText.Text = xmlDoc.OuterXml;
  76. }
  77. catch (Exception ex)
  78. {
  79. MessageBox.Show(ex.Message);
  80. }
  81. finally
  82. {
  83. // Clear the RSA key.
  84. rsaKey.Clear();
  85. }
  86. }
  87. private void btnDecrypt_Click(object sender, EventArgs e)
  88. {
  89. // Create an XmlDocument object
  90. XmlDocument xmlDoc = new XmlDocument();
  91. // Load an XML file into the XmlDocument object.
  92. try
  93. {
  94. xmlDoc.Load("test.xml");
  95. }
  96. catch (Exception ex)
  97. {
  98. Console.WriteLine(ex.Message);
  99. }
  100. CspParameters cspParams = new CspParameters();
  101. cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
  102. //////////////////////////////////////////////////////////////////////
  103. // Get the RSA key from the key container. This key will decrypt
  104. // a symmetric key that was imbedded in the XML document
  105. //
  106. RSACryptoServiceProvider rsaKey =
  107. new RSACryptoServiceProvider(cspParams);
  108. try
  109. {
  110. //////////////////////////////////////////////////////////////////
  111. // Call Decrypt subroutine to decrypt data
  112. //
  113. // Decrypt the elements.
  114. Decrypt(xmlDoc, rsaKey, "rsaKey");
  115. // Save the XML document.
  116. xmlDoc.Save("test.xml");
  117. // Display the encrypted XML to the console.
  118. MessageBox.Show("Decrypted XML:");
  119. tbxRecoveredPlaintext.Text = xmlDoc.OuterXml;
  120. }
  121. catch (Exception ex)
  122. {
  123. MessageBox.Show(ex.Message);
  124. }
  125. finally
  126. {
  127. // Clear the RSA key.
  128. rsaKey.Clear();
  129. }
  130. }
  131. private void XMLEncryptDecryptForm_Load(object sender, EventArgs e)
  132. {
  133. GenerateXmlDocument();
  134. tbxPlaintext.Text = xmlDoc.OuterXml;
  135. }
  136. /// <summary>
  137. /// Generate XmlDocument
  138. /// </summary>
  139. private void GenerateXmlDocument()
  140. {
  141. XDocument xdoc = new XDocument(
  142. new XDeclaration("1.0", "utf-8", "yes"),
  143. new XComment("This is a comment"),
  144. new XElement("invoice",
  145. new XElement("items",
  146. new XElement("item",
  147. new XElement("desc", ""),
  148. new XElement("unitprice", "14.95"),
  149. new XElement("quantity", "1")),
  150. new XElement("creditcard",
  151. new XElement("number", "19834209"),
  152. new XElement("expiry", "02/02/2002")
  153. ))));
  154. xdoc.Save("test.xml");
  155. xmlDoc = new XmlDocument();
  156. xmlDoc.Load("test.xml");
  157. }
  158. public static void Encrypt(XmlDocument Doc, string ElementToEncrypt,
  159. string EncryptionElementID, RSA Alg, string KeyName)
  160. {
  161. //////////////////////////////////////////////////////////////////////
  162. // Check the arguments
  163. //
  164. if (Doc == null)
  165. throw new ArgumentNullException("Doc");
  166. if (ElementToEncrypt == null)
  167. throw new ArgumentNullException("ElementToEncrypt");
  168. if (EncryptionElementID == null)
  169. throw new ArgumentNullException("EncryptionElementID");
  170. if (Alg == null)
  171. throw new ArgumentNullException("Alg");
  172. if (KeyName == null)
  173. throw new ArgumentNullException("KeyName");
  174. // Find the specified element in the XmlDocument object and create a
  175. // new XmlElemnt object.
  176. XmlElement elementToEncrypt =
  177. Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
  178. // Throw an XmlException if the element was not found.
  179. if (elementToEncrypt == null)
  180. {
  181. throw new XmlException("The specified element was not found");
  182. }
  183. RijndaelManaged sessionKey = null;
  184. try
  185. {
  186. /////////////////////////////////////////////////////////////////
  187. // Create a new instance of the EncryptedXml class and use it
  188. // to encrypt the XmlElement with the a new random symmetric key
  189. //
  190. // Create a 256 bit Rijndael key.
  191. sessionKey = new RijndaelManaged();
  192. sessionKey.KeySize = 256;
  193. EncryptedXml eXml = new EncryptedXml();
  194. byte[] encryptedElement = eXml.EncryptData(elementToEncrypt,
  195. sessionKey, false);
  196. /////////////////////////////////////////////////////////////////
  197. // Construct an EncryptedData object and populate it with the
  198. // desired encryption information.
  199. //
  200. EncryptedData edElement = new EncryptedData();
  201. edElement.Type = EncryptedXml.XmlEncElementUrl;
  202. edElement.Id = EncryptionElementID;
  203. /////////////////////////////////////////////////////////////////
  204. // Create an EncryptionMethod element so that the receiver knows
  205. // which algorithm to use for decryption.
  206. //
  207. edElement.EncryptionMethod =
  208. new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
  209. // Encrypt the session key and add it to an EncryptedKey element.
  210. EncryptedKey ek = new EncryptedKey();
  211. byte[] encryptedKey =
  212. EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
  213. ek.CipherData = new CipherData(encryptedKey);
  214. ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
  215. /////////////////////////////////////////////////////////////////
  216. // Create a new DataReference element for the KeyInfo element.This
  217. // optional element specifies which EncryptedData uses this key.
  218. // An XML document can have multiple EncryptedData elements that use
  219. // different keys.
  220. //
  221. DataReference dRef = new DataReference();
  222. // Specify the EncryptedData URI.
  223. dRef.Uri = "#" + EncryptionElementID;
  224. // Add the DataReference to the EncryptedKey.
  225. ek.AddReference(dRef);
  226. // Add the encrypted key to the EncryptedData object.
  227. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
  228. // Set the KeyInfo element to specify the name of the RSA key.
  229. // Create a new KeyInfo element.
  230. edElement.KeyInfo = new KeyInfo();
  231. // Create a new KeyInfoName element.
  232. KeyInfoName kin = new KeyInfoName();
  233. // Specify a name for the key.
  234. kin.Value = KeyName;
  235. // Add the KeyInfoName element to the EncryptedKey object.
  236. ek.KeyInfo.AddClause(kin);
  237. // Add the encrypted key to the EncryptedData object.
  238. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
  239. /////////////////////////////////////////////////////////////////
  240. // Add the encrypted element data to the EncryptedData object.
  241. //
  242. edElement.CipherData.CipherValue = encryptedElement;
  243. // Replace the element from the original XmlDocument object with
  244. // the EncryptedData element
  245. EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
  246. }
  247. catch (Exception e)
  248. {
  249. // re-throw the exception.
  250. throw e;
  251. }
  252. finally
  253. {
  254. if (sessionKey != null)
  255. {
  256. sessionKey.Clear();
  257. }
  258. }
  259. }
  260. public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
  261. {
  262. //////////////////////////////////////////////////////////////////////
  263. // Check the arguments
  264. //
  265. if (Doc == null)
  266. throw new ArgumentNullException("Doc");
  267. if (Alg == null)
  268. throw new ArgumentNullException("Alg");
  269. if (KeyName == null)
  270. throw new ArgumentNullException("KeyName");
  271. //////////////////////////////////////////////////////////////////////
  272. // Create a new EncryptedXml object to decrypt data
  273. //
  274. EncryptedXml exml = new EncryptedXml(Doc);
  275. // Add a key-name mapping.
  276. // This method can only decrypt documents
  277. // that present the specified key name.
  278. exml.AddKeyNameMapping(KeyName, Alg);
  279. // Decrypt the element.
  280. exml.DecryptDocument();
  281. }
  282. }
  283. }