PageRenderTime 14ms CodeModel.GetById 1ms app.highlight 9ms RepoModel.GetById 1ms 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
 30#region Using Directives
 31using System;
 32using System.Collections.Generic;
 33using System.ComponentModel;
 34using System.Data;
 35using System.Drawing;
 36using System.Linq;
 37using System.Text;
 38using System.Windows.Forms;
 39using System.Xml.Linq;
 40using System.Xml;
 41using System.Security.Cryptography;
 42using System.Security.Cryptography.Xml;
 43#endregion
 44
 45
 46namespace CSXmlEncryption
 47{
 48    public partial class MainForm : Form
 49    {
 50        // XmlDocument object for encryption and decryption
 51        private XmlDocument xmlDoc;
 52
 53        public MainForm()
 54        {
 55            InitializeComponent();
 56        }
 57
 58        private void btnEncrypt_Click(object sender, EventArgs e)
 59        {
 60            /////////////////////////////////////////////////////////////////////
 61            // Create a new RSA key and save it in the container. 
 62            // This key will encrypt a symmetric key, which 
 63            // Will then be encryped in the XML document
 64            //
 65
 66            CspParameters cspParams = new CspParameters();
 67            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
 68            RSACryptoServiceProvider rsaKey =
 69                new RSACryptoServiceProvider(cspParams);
 70            this.tbxRSAParameters.Text = rsaKey.ToXmlString(true);
 71            try
 72            {
 73                /////////////////////////////////////////////////////////////////
 74                // Call Encrypt subroutine to encrypt the "creditcard" element
 75                // 
 76
 77                Encrypt(xmlDoc, "creditcard", "EncryptedElement1", rsaKey, "rsaKey");
 78
 79                // Save the XML document.
 80                xmlDoc.Save("test.xml");
 81
 82                // Display message of "Encrypted XML" to user
 83                MessageBox.Show("Encrypted XML");
 84
 85                tbxCipherTextasText.Text = xmlDoc.OuterXml;
 86
 87            }
 88            catch (Exception ex)
 89            {
 90                MessageBox.Show(ex.Message);
 91            }
 92            finally
 93            {
 94                // Clear the RSA key.
 95                rsaKey.Clear();
 96            }
 97        }
 98
 99        private void btnDecrypt_Click(object sender, EventArgs e)
100        {
101            // Create an XmlDocument object
102            XmlDocument xmlDoc = new XmlDocument();
103            // Load an XML file into the XmlDocument object.
104            try
105            {
106                xmlDoc.Load("test.xml");
107            }
108            catch (Exception ex)
109            {
110                Console.WriteLine(ex.Message);
111            }
112
113            CspParameters cspParams = new CspParameters();
114            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
115
116
117            //////////////////////////////////////////////////////////////////////
118            // Get the RSA key from the key container.  This key will decrypt
119            // a symmetric key that was imbedded in the XML document
120            //
121
122            RSACryptoServiceProvider rsaKey =
123                new RSACryptoServiceProvider(cspParams);
124
125            try
126            {
127                //////////////////////////////////////////////////////////////////
128                // Call Decrypt subroutine to decrypt data
129                // 
130
131                // Decrypt the elements.
132                Decrypt(xmlDoc, rsaKey, "rsaKey");
133                // Save the XML document.
134                xmlDoc.Save("test.xml");
135                // Display the encrypted XML to the console.
136                MessageBox.Show("Decrypted XML:");
137                tbxRecoveredPlaintext.Text = xmlDoc.OuterXml;
138            }
139            catch (Exception ex)
140            {
141                MessageBox.Show(ex.Message);
142            }
143            finally
144            {
145                // Clear the RSA key.
146                rsaKey.Clear();
147            }
148        }
149
150        private void XMLEncryptDecryptForm_Load(object sender, EventArgs e)
151        {
152            GenerateXmlDocument();
153            tbxPlaintext.Text = xmlDoc.OuterXml;
154        }
155        /// <summary>
156        /// Generate XmlDocument 
157        /// </summary>
158        private void GenerateXmlDocument()
159        {
160            XDocument xdoc = new XDocument(
161                new XDeclaration("1.0", "utf-8", "yes"),
162                new XComment("This is a comment"),
163                new XElement("invoice",
164                    new XElement("items",
165                        new XElement("item",
166                            new XElement("desc", ""),
167                            new XElement("unitprice", "14.95"),
168                            new XElement("quantity", "1")),
169                            new XElement("creditcard",
170                                new XElement("number", "19834209"),
171                                new XElement("expiry", "02/02/2002")
172                                ))));
173            xdoc.Save("test.xml");
174            xmlDoc = new XmlDocument();
175            xmlDoc.Load("test.xml");
176        }
177
178        public static void Encrypt(XmlDocument Doc, string ElementToEncrypt,
179            string EncryptionElementID, RSA Alg, string KeyName)
180        {
181            //////////////////////////////////////////////////////////////////////
182            // Check the arguments
183            // 
184
185            if (Doc == null)
186                throw new ArgumentNullException("Doc");
187            if (ElementToEncrypt == null)
188                throw new ArgumentNullException("ElementToEncrypt");
189            if (EncryptionElementID == null)
190                throw new ArgumentNullException("EncryptionElementID");
191            if (Alg == null)
192                throw new ArgumentNullException("Alg");
193            if (KeyName == null)
194                throw new ArgumentNullException("KeyName");
195
196            // Find the specified element in the XmlDocument object and create a
197            // new XmlElemnt object.
198            XmlElement elementToEncrypt =
199                Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
200
201            // Throw an XmlException if the element was not found.
202            if (elementToEncrypt == null)
203            {
204                throw new XmlException("The specified element was not found");
205            }
206
207            RijndaelManaged sessionKey = null;
208            try
209            {
210                /////////////////////////////////////////////////////////////////
211                // Create a new instance of the EncryptedXml class and use it
212                // to encrypt the XmlElement with the a new random symmetric key
213                // 
214
215                // Create a 256 bit Rijndael key.
216                sessionKey = new RijndaelManaged();
217                sessionKey.KeySize = 256;
218
219                EncryptedXml eXml = new EncryptedXml();
220
221                byte[] encryptedElement = eXml.EncryptData(elementToEncrypt,
222                    sessionKey, false);
223
224
225                /////////////////////////////////////////////////////////////////
226                // Construct an EncryptedData object and populate it with the 
227                // desired encryption information.
228                // 
229
230                EncryptedData edElement = new EncryptedData();
231                edElement.Type = EncryptedXml.XmlEncElementUrl;
232                edElement.Id = EncryptionElementID;
233
234
235                /////////////////////////////////////////////////////////////////
236                // Create an EncryptionMethod element so that the receiver knows 
237                // which algorithm to use for decryption.
238                //
239
240                edElement.EncryptionMethod =
241                    new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
242                // Encrypt the session key and add it to an EncryptedKey element.
243                EncryptedKey ek = new EncryptedKey();
244                byte[] encryptedKey =
245                    EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
246                ek.CipherData = new CipherData(encryptedKey);
247                ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
248
249
250                /////////////////////////////////////////////////////////////////
251                // Create a new DataReference element for the KeyInfo element.This 
252                // optional element specifies which EncryptedData uses this key. 
253                // An XML document can have multiple EncryptedData elements that use
254                // different keys.
255                //
256
257                DataReference dRef = new DataReference();
258                // Specify the EncryptedData URI.
259                dRef.Uri = "#" + EncryptionElementID;
260                // Add the DataReference to the EncryptedKey.
261                ek.AddReference(dRef);
262                // Add the encrypted key to the EncryptedData object.
263                edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
264                // Set the KeyInfo element to specify the name of the RSA key.
265                // Create a new KeyInfo element.
266                edElement.KeyInfo = new KeyInfo();
267                // Create a new KeyInfoName element.
268                KeyInfoName kin = new KeyInfoName();
269                // Specify a name for the key.
270                kin.Value = KeyName;
271                // Add the KeyInfoName element to the EncryptedKey object.
272                ek.KeyInfo.AddClause(kin);
273                // Add the encrypted key to the EncryptedData object.
274                edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
275
276
277                /////////////////////////////////////////////////////////////////
278                // Add the encrypted element data to the EncryptedData object.
279                //
280
281                edElement.CipherData.CipherValue = encryptedElement;
282                // Replace the element from the original XmlDocument object with 
283                // the EncryptedData element           
284                EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
285            }
286            catch (Exception e)
287            {
288                // re-throw the exception.
289                throw e;
290            }
291            finally
292            {
293                if (sessionKey != null)
294                {
295                    sessionKey.Clear();
296                }
297            }
298        }
299
300        public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
301        {
302            //////////////////////////////////////////////////////////////////////
303            // Check the arguments
304            //
305
306            if (Doc == null)
307                throw new ArgumentNullException("Doc");
308            if (Alg == null)
309                throw new ArgumentNullException("Alg");
310            if (KeyName == null)
311                throw new ArgumentNullException("KeyName");
312
313
314            //////////////////////////////////////////////////////////////////////
315            // Create a new EncryptedXml object to decrypt data
316            //
317
318            EncryptedXml exml = new EncryptedXml(Doc);
319            // Add a key-name mapping.
320            // This method can only decrypt documents
321            // that present the specified key name.
322            exml.AddKeyNameMapping(KeyName, Alg);
323            // Decrypt the element.
324            exml.DecryptDocument();
325        }
326    }
327}