1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Transmitting a DataSet Securely docx

12 290 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 12
Dung lượng 38,13 KB

Nội dung

[ Team LiB ] Recipe 5.7 Transmitting a DataSet Securely Problem You need to securely send a DataSet over a connection that is not secure. Solution Encrypt and decrypt the DataSet using the .NET cryptographic services, and serialize and save the encrypted DataSet to a stream (such as a file or network stream). The sample code contains two event handlers: Encrypt Button.Click The first Button.Click creates a DataSet and encrypts it using the algorithm specified by the user and writes the encrypted DataSet to a file. Decrypt Button.Click The second Button.Click decrypts a file containing a DataSet previously encrypted using an algorithm specified by the user and uses the file to recreate the DataSet previously encrypted. The C# code is shown in Example 5-7 . Example 5-7. File: SecureTransmissionForm.cs // Namespaces, variables, and constants using System; using System.Configuration; using System.Windows.Forms; using System.Xml; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography; using System.Data; using System.Data.SqlClient; // Table name constants private const String ORDERS_TABLE = "Orders"; private const String ORDERDETAILS_TABLE = "OrderDetails"; // Relation name constants private const String ORDERS_ORDERDETAILS_RELATION = "Orders_OrderDetails_Relation"; // Field name constants private const String ORDERID_FIELD = "OrderID"; private RSACryptoServiceProvider rSAReceiver; private const int keySize = 128; // DES key and IV private Byte[] dESKey = new Byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; private Byte[] dESIV = new Byte[] {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; // RC2 key and IV private Byte[] rC2Key = new Byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; private Byte[] rC2IV = new Byte[] {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; // Rijndael key and IV private Byte[] rijndaelKey = new Byte[] {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F}; private Byte[] rijndaelIV = new Byte[] {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F}; // triple DES key and IV private Byte[] tDESKey = new Byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; private Byte[] tDESIV = new Byte[] {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37}; // . . . [Serializable( )] internal class EncryptedMessage { public byte[] Body; // RC2 encrypted public byte[] Key; // RSA encrypted RC2 key public byte[] IV; // RC2 initialization vector } private void encryptButton_Click(object sender, System.EventArgs e) { DataSet ds = new DataSet( ); SqlDataAdapter da; // Fill the Order table and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM Orders", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderTable = new DataTable(ORDERS_TABLE); da.FillSchema(orderTable, SchemaType.Source); da.Fill(orderTable); ds.Tables.Add(orderTable); // Fill the OrderDetails table and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM [Order Details]", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderDetailTable = new DataTable(ORDERDETAILS_TABLE); da.FillSchema(orderDetailTable, SchemaType.Source); da.Fill(orderDetailTable); ds.Tables.Add(orderDetailTable); // Create a relation between the tables. ds.Relations.Add(ORDERS_ORDERDETAILS_RELATION, ds.Tables[ORDERS_TABLE].Columns[ORDERID_FIELD], ds.Tables[ORDERDETAILS_TABLE].Columns[ORDERID_FIELD], true); // Clear the grid. dataGrid.DataSource = null; if(rSARadioButton.Checked) { // Asymmetric algorithm EncryptedMessage em = new EncryptedMessage( ); // RC2 symmetric algorithm to encode the DataSet RC2CryptoServiceProvider rC2 = new RC2CryptoServiceProvider( ); rC2.KeySize = keySize; // Generate RC2 Key and IV. rC2.GenerateKey( ); rC2.GenerateIV( ); // Get the receiver's RSA public key. RSACryptoServiceProvider rSA = new RSACryptoServiceProvider( ); rSA.ImportParameters(rSAReceiver.ExportParameters(false)); try { // Encrypt the RC2 key and IV with the receiver's RSA // public key. em.Key = rSA.Encrypt(rC2.Key, false); em.IV = rSA.Encrypt(rC2.IV, false); } catch(CryptographicException ex) { MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Cursor.Current = Cursors.WaitCursor; // Use the CryptoStream to write the encrypted DataSet to the // MemoryStream. MemoryStream ms = new MemoryStream( ); CryptoStream cs = new CryptoStream(ms, rC2.CreateEncryptor( ), CryptoStreamMode.Write); ds.WriteXml(cs, XmlWriteMode.WriteSchema); cs.FlushFinalBlock( ); em.Body = ms.ToArray( ); cs.Close( ); ms.Close( ); // Serialize the encrypted message to a file. Stream s = File.Open(System.IO.Path.GetTempPath( ) + @"\rsa.dat", FileMode.Create); BinaryFormatter bf = new BinaryFormatter( ); bf.Serialize(s, em); s.Close( ); Cursor.Current = Cursors.Default; MessageBox.Show("Encryption complete.", "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { SaveFileDialog sfd; sfd = new SaveFileDialog( ); sfd.InitialDirectory = System.IO.Path.GetTempPath( ); sfd.Filter = "All files (*.*)|*.*"; sfd.FilterIndex = 0; if (sfd.ShowDialog( ) == DialogResult.OK) { FileStream fsWrite = null; try { fsWrite = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write); } catch (Exception ex) { MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Cursor.Current = Cursors.WaitCursor; // Symmetric algorithms byte[] key = null; byte[] iV = null; SymmetricAlgorithm sa = null; if(dESRadioButton.Checked) { sa = new DESCryptoServiceProvider( ); key = dESKey; iV = dESIV; } else if(rc2RadioButton.Checked) { sa = new RC2CryptoServiceProvider( ); sa.KeySize = 128; key = rC2Key; iV = rC2IV; } else if(rijndaelRadioButton.Checked) { sa = new RijndaelManaged( ); key = rijndaelKey; iV = rijndaelIV; } else if(tripleDESRadioButton.Checked) { sa = new TripleDESCryptoServiceProvider( ); key = tDESKey; iV = tDESIV; } // Encrypt the DataSet CryptoStream cs = null; try { cs = new CryptoStream(fsWrite, sa.CreateEncryptor(key, iV), CryptoStreamMode.Write); ds.WriteXml(cs, XmlWriteMode.WriteSchema); cs.Close( ); MessageBox.Show("Encryption complete.", "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { fsWrite.Close( ); Cursor.Current = Cursors.Default; } } } } private void decryptButton_Click(object sender, System.EventArgs e) { dataGrid.DataSource = null; DataSet ds = new DataSet( ); if(rSARadioButton.Checked) { // Asymmetric algorithm // Deserialize the encrypted message from a file. Stream s = null; try { s = File.Open(System.IO.Path.GetTempPath( ) + @"\rsa.dat", FileMode.Open); } catch (Exception ex) { MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } BinaryFormatter bf = new BinaryFormatter( ); EncryptedMessage em = (EncryptedMessage)bf.Deserialize(s); s.Close( ); // RC2 symmetric algorithm to decode the DataSet RC2CryptoServiceProvider rC2 = new RC2CryptoServiceProvider( ); rC2.KeySize = keySize; // Decrypt the RC2 key and IV using the receiver's RSA private // key. try { rC2.Key = rSAReceiver.Decrypt(em.Key, false); rC2.IV = rSAReceiver.Decrypt(em.IV, false); } catch (CryptographicException ex) { MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Cursor.Current = Cursors.WaitCursor; // Put the message body into the MemoryStream. MemoryStream ms = new MemoryStream(em.Body); // Use the CryptoStream to read the encrypted DataSet from the // MemoryStream. CryptoStream cs = new CryptoStream(ms, rC2.CreateDecryptor( ), CryptoStreamMode.Read); ds.ReadXml(cs, XmlReadMode.ReadSchema); cs.Close( ); dataGrid.DataSource = ds.DefaultViewManager; Cursor.Current = Cursors.Default; } else { // Symmetric algorithm OpenFileDialog ofd; ofd = new OpenFileDialog( ); ofd.InitialDirectory = System.IO.Path.GetTempPath( ); ofd.Filter = "All files (*.*)|*.*"; ofd.FilterIndex = 0; if (ofd.ShowDialog( ) == DialogResult.OK) { FileStream fsRead = null; try { fsRead = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read); } catch(Exception ex) { dataGrid.DataSource = null; MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Cursor.Current = Cursors.WaitCursor; SymmetricAlgorithm sa = null; byte[] key = null; byte[] iV = null; if(dESRadioButton.Checked) { sa = new DESCryptoServiceProvider( ); key = dESKey; iV = dESIV; } else if(rc2RadioButton.Checked) { sa = new RC2CryptoServiceProvider( ); sa.KeySize = 128; key = rC2Key; iV = rC2IV; } else if(rijndaelRadioButton.Checked) { sa = new RijndaelManaged( ); key = rijndaelKey; iV = rijndaelIV; } else if(tripleDESRadioButton.Checked) { sa = new TripleDESCryptoServiceProvider( ); key = tDESKey; iV = tDESIV; } // Decrypt the stream into the DataSet. CryptoStream cs = null; try { cs = new CryptoStream(fsRead, sa.CreateDecryptor(key, iV), CryptoStreamMode.Read); ds.ReadXml(cs, XmlReadMode.ReadSchema); cs.Close( ); dataGrid.DataSource = ds.DefaultViewManager; } catch(Exception ex) { dataGrid.DataSource = null; MessageBox.Show(ex.Message, "Securing Transmission", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { fsRead.Close( ); Cursor.Current = Cursors.Default; } } } } Discussion Cryptography protects data from being viewed or modified and provides security when transmitting or serializing the data in environments that are otherwise not secure. The data can be encrypted, transmitted or serialized in its encrypted state, and later decrypted. If the data is intercepted in its encrypted state, it is much more difficult to access the data because it is necessary to first decrypt it. Encryption algorithms are of two types: symmetric key and asymmetric key. A brief overview follows. Symmetric key algorithms use a secret key to both encrypt and decrypt the data. Because [...]... recreate the DataSet If the asymmetric (RSA) algorithm is chosen, the sample generates both an RC2 (symmetric) key and an IV The receiver RSACryptoServiceProvider object is created in the constructor and because the default constructor is used, a new public/private key pair is generated for the receiver each time the application is run This means that for this example, an asymmetric encryption of the DataSet. .. secret and a public key that can be made available to anyone These key pairs are used both to encrypt data (data encrypted with the public key can only be decrypted with the private key) and sign data (data signed with the private key can only be verified with the public key) The public key is used to encrypt data that is being sent to the owner of the private key while the private key is used to digitally... the DataSet stored in the Body variable of the EncryptedMessage object The DataSet is recreated from the XML Although this example demonstrates serializing the encrypted DataSet to a file, you can use the same technique to serialize the DataSet to a stream so that it can be transmitted securely in an environment that is otherwise not secure [ Team LiB ] ...the same key is used both to encrypt and decrypt the data, it must be kept secret Symmetric algorithms are also known as secret key algorithms Symmetric key algorithms are very fast compared to asymmetric algorithms and are therefore suitable for encrypting large amounts of data The NET Framework classes that implement symmetric key algorithms are: • • • • DESCryptoServiceProvider... then called to encrypt both the RC2 key and the IV and store them to the appropriate variables of an EncryptedMessage object, defined as an internal class Next, the CryptoStream object is used to write the XML representation of the DataSet, encrypted using the RC2 key and IV, to a MemoryStream object, which is then stored in the Body variable of the EncryptedMessage object Finally, the EncryptedMessage... sign data to allow the origin of communication to be verified and to ensure that those communications have not been altered While more secure, asymmetric key algorithms are much slower than symmetric algorithms The NET Framework classes that implement asymmetric key algorithms are: • • DSACryptoServiceProvider RSACryptoServiceProvider To overcome the performance limitations of asymmetric key algorithms... much faster than using the public key The encrypted key and data are then sent to the owner of the public/private key pair The recipient uses the private key to decrypt the symmetric key and can then use the symmetric key to decrypt the data In the sample code, both the encryption and decryption use the key and IV values defined using variable initializers only as a convenience While the same key and... RC2CryptoServiceProvider RijndaelManaged TripleDESCryptoServiceProvider The symmetric key algorithms provided in these classes use an initialization vector (IV) in addition to the key so that an identical plaintext message produces different ciphertext when using the same key with a different IV Good practice is to use a different IV with each encryption Asymmetric key algorithms use both a private key that must be kept... which the encrypted DataSet is written In each case, the specified cryptographic service provider is created, the key and IV are set, and a CryptoStream object is used to encrypt the XML representation of the DataSet, which is written to the specified file To decrypt the file, a CryptoStream object is used to decrypt the contents of the file into an XML representation of the DataSet, which is subsequently... key and IV values must be used when encrypting and decrypting data, these values will normally be set according to the specific requirements of the application To encrypt the data, the user can choose between four symmetric algorithms (DES, RC2, Rijndael, and Triple DES) and one asymmetric algorithm (RSA) If one of the symmetric algorithms is chosen, the user is presented with a file dialog to specify . ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderDetailTable = new DataTable(ORDERDETAILS_TABLE); da.FillSchema(orderDetailTable, SchemaType.Source); da.Fill(orderDetailTable); ds.Tables.Add(orderDetailTable);. ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderTable = new DataTable(ORDERS_TABLE); da.FillSchema(orderTable, SchemaType.Source); da.Fill(orderTable); ds.Tables.Add(orderTable);

Ngày đăng: 14/12/2013, 18:16

TỪ KHÓA LIÊN QUAN

w