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

Tài liệu Transmitting a DataSet Securely docx

12 293 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Tiêu đề Transmitting a DataSet Securely
Tác giả Team Lib
Thể loại Recipe
Định dạng
Số trang 12
Dung lượng 38,13 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 co

Trang 1

[ 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";

Trang 2

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};

//

Trang 3

[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)

{

Trang 4

// 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);

Trang 5

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)

Trang 6

{

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)

{

Trang 7

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;

Trang 8

// 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

Trang 9

{

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;

Trang 10

}

// 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

Trang 11

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

• 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 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 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 with large

amounts of data and still benefit from the much stronger security they provide, only a symmetric key is encrypted, which is in turn used to encrypt the data Here's how it

works: A public key is obtained from the person to whom the data is being sent A

symmetric key is generated by the sender and subsequently encrypted using the public key received from the recipient The data is then encrypted using the symmetric key; this

is 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 IV values must

be used when encrypting and decrypting data, these values will normally be set according

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

TỪ KHÓA LIÊN QUAN

w