Tuesday, October 28, 2008

My C# Template - For Web and Windows Applications

// I DESIGNED THIS TEMPLATE WHILE IN THIRD YEAR,
// IN READINESS FOR MY FOURTH YEAR PROJECT.
// FEATURES INCLUDE CRYPTOGRAPHY, DB ACCESS


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Data;
using System.Windows.Forms;

using System.Security.Cryptography;
using Fleet_Management_System;
using DataworldResearchServicesKenya;
using Fleet_Management_System.App_Interface;
using Fleet_Management_System.App_Data;
using Fleet_Management_System.Properties;

//using sqlMobile = System.Data.SqlServerCe;
using Access = System.Data.OleDb;

using OG_RA = DataworldResearchServicesKenya.cRijndaelAlgorithm;
using OG_DB = DataworldResearchServicesKenya.cDatabase;
using OG_CN = DataworldResearchServicesKenya.cConnect;
using OG_PRG = DataworldResearchServicesKenya.Program;

namespace DataworldResearchServicesKenya
{

///
/// NOTE: THIS IS MY MAIN AREA OF RESEARCH, FOR THE FINAL YEAR PROJECT.
/// Illustrates the use of cRijndaelAlgorithm class to encrypt and decrypt data.
/// This class uses a symmetric key algorithm (Rijndael/AES) to encrypt and
/// decrypt data. As long as encryption and decryption routines use the same
/// parameters to generate the keys, the keys are guaranteed to be the same.
///
/// This Class has been sealed against modifications via inheritance.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public sealed class cRijndaelAlgorithm
{
///
/// Passphrase can be any string.
/// Used to derive a pseudo-random password,
/// which is used to generate the encryption key.
///
/// In this final year project,
/// I assume that this passphrase is an ASCII string.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public string passPhrase = "KenyaPolice";

///
/// saltValue can be any string.
/// Used along with passphrase to generate password.
///
/// In this final year project,
/// I assume that this saltValue is an ASCII string.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public string saltValue = "UtumishiKwaWote";

///
/// hashAlgorithm can be "MD5" or "SHA1".
/// SHA1 hashes are a bit slower, but more secure than MD5 hashes.
/// the hashAlgorithm is used to generate the password.
///
/// In this final year project,
/// I implemented cryptography using SHA1 hashes.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public string hashAlgorithm = "SHA1";

///
/// Initialization vector (or IV/initVector) must be 16 bytes
/// This value is required to encrypt the first block of plaintext data.
/// For RijndaelManaged class IV must be exactly 16 ASCII characters long.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public string initVector = "@1B2c3D4e5F6g7H8";

///
/// passwordIterations can be any number.
/// It is the number of iterations used to generate password.
///
///
/// In this final year project,
/// I randomly generate an integer,
/// between two and five, for each new session.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public int passwordIterations = 2;

///
/// Size of encryption key in bits.
/// keySize can be 128, 192 or 256.
/// Longer keys are more secure than shorter keys.
///
/// NOTE: [NIST only documented for 128 bit keys]
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public int keySize = 256;

///
/// Class constructor
/// Designed by: Ogolla Onyango Fredrick - Final year project - CS 282 - 0515/02
///
public cRijndaelAlgorithm()
{
try
{
//create random passPhrase for the session
this.passPhrase = (this.sEncrypt(this.passPhrase));

//create random saltValue for the session
this.saltValue = (this.sEncrypt(this.saltValue));
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// Encrypts specified plaintext using Rijndael symmetric key algorithm
/// and returns a base64-encoded result.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
///
///

/// Plaintext value to be encrypted.
///
///
///
/// Encrypted value formatted as a base64-encoded string.
///
public string sEncrypt(string plainText)
{
string r = null;
try
{
///
/// Converted string [initVector] defining encryption key
/// characteristics into byte arrays.
/// Assumes that strings only contain ASCII codes.
/// If strings include Unicode characters, use;
/// Unicode, UTF7, UTF8, UTF32, BigEndianUnicode or Default).
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
byte[] initVectorBytes = Encoding.ASCII.GetBytes(this.initVector);

///
/// Converted string [initVector] defining encryption key
/// characteristics into byte arrays.
/// Assumes that strings only contain ASCII codes.
/// If strings include Unicode characters, use;
/// Unicode, UTF7, UTF8, UTF32, BigEndianUnicode or Default).
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
byte[] saltValueBytes = Encoding.ASCII.GetBytes(this.saltValue);

// Convert our plaintext into a byte array.
// Let us assume that plaintext contains UTF8-encoded characters.
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

// First, we must create a password, from which the key will be derived.
// This password will be generated from the specified passphrase and
// salt value. The password will be created using the specified hash
// algorithm. Password creation can be done in several iterations.
PasswordDeriveBytes password = new PasswordDeriveBytes(
this.passPhrase,
saltValueBytes,
this.hashAlgorithm,
this.passwordIterations);

// Use the password to generate pseudo-random bytes for the encryption
// key. Specify the size of the key in bytes (instead of bits).
byte[] keyBytes = password.GetBytes(this.keySize / 8);

// Create uninitialized Rijndael encryption object.
RijndaelManaged symmetricKey = new RijndaelManaged();

// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC;

// Generate encryptor from the existing key bytes and initialization
// vector. Key size will be defined based on the number of the key
// bytes.
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
keyBytes,
initVectorBytes);

// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = new MemoryStream();

// Define cryptographic stream (always use Write mode for encryption).
CryptoStream cryptoStream = new CryptoStream(memoryStream,
encryptor,
CryptoStreamMode.Write);
// Start encrypting.
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

// Finish encrypting.
cryptoStream.FlushFinalBlock();

// Convert our encrypted data from a memory stream into a byte array.
byte[] cipherTextBytes = memoryStream.ToArray();

// Close both streams.
memoryStream.Close();
cryptoStream.Close();

// Convert encrypted data into a base64-encoded string.
string cipherText = Convert.ToBase64String(cipherTextBytes);

// Return encrypted string.
r = cipherText;
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
return r;
}

///
/// Decrypts specified ciphertext using Rijndael symmetric key algorithm.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
///
/// Base64-formatted ciphertext value.
///
///
/// Decrypted string value.
///
///
/// Most of the logic in this function is similar to the Encrypt
/// logic. In order for decryption to work, all parameters of this function
/// - except cipherText value - must match the corresponding parameters of
/// the Encrypt function which was called to generate the
/// ciphertext.
///
public string sDecrypt(string cipherText)
{
string r = null;
try
{
///
/// Converted string [initVector] defining encryption key
/// characteristics into byte arrays.
/// Assumes that strings only contain ASCII codes.
/// If strings include Unicode characters, use;
/// Unicode, UTF7, UTF8, UTF32, BigEndianUnicode or Default).
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
byte[] initVectorBytes = Encoding.ASCII.GetBytes(this.initVector);

///
/// Converted string [saltValue] defining encryption key
/// characteristics into byte arrays.
/// Assumes that strings only contain ASCII codes.
/// If strings include Unicode characters, use;
/// Unicode, UTF7, UTF8, UTF32, BigEndianUnicode or Default).
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
byte[] saltValueBytes = Encoding.ASCII.GetBytes(this.saltValue);

// Convert our ciphertext into a byte array.
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

// First, we must create a password, from which the key will be
// derived. This password will be generated from the specified
// passphrase and salt value. The password will be created using
// the specified hash algorithm. Password creation can be done in
// several iterations.
PasswordDeriveBytes password = new PasswordDeriveBytes(
this.passPhrase,
saltValueBytes,
this.hashAlgorithm,
this.passwordIterations);

// Use the password to generate pseudo-random bytes for the encryption
// key. Specify the size of the key in bytes (instead of bits).
byte[] keyBytes = password.GetBytes(this.keySize / 8);

// Create uninitialized Rijndael encryption object.
RijndaelManaged symmetricKey = new RijndaelManaged();

// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC;

// Generate decryptor from the existing key bytes and initialization
// vector. Key size will be defined based on the number of the key
// bytes.
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
keyBytes,
initVectorBytes);

// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);

// Define cryptographic stream (always use Read mode for encryption).
CryptoStream cryptoStream = new CryptoStream(memoryStream,
decryptor,
CryptoStreamMode.Read);

// Since at this point I don't know what the size of decrypted data
// will be, I allocate the buffer long enough to hold ciphertext;
// plaintext is never longer than ciphertext.
byte[] plainTextBytes = new byte[cipherTextBytes.Length];

// Start decrypting.
int decryptedByteCount = cryptoStream.Read(plainTextBytes,
0,
plainTextBytes.Length);

// Close both streams.
memoryStream.Close();
cryptoStream.Close();

// Convert decrypted data into a string.
// Assumes that the original plaintext string was UTF8-encoded.
string plainText = Encoding.UTF8.GetString(plainTextBytes,
0,
decryptedByteCount);

// Return decrypted string.
r = plainText;

}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
return r;
}
}//end of cRijndaelAlgorithm

///
/// This class is used for all reads/writes to the database.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public class cConnect
{
//ALL VARIABLE MEMBERS ARE PRIVATE FOR ABSTRACTION IN IMPLEMENTATION PURPOSES
//private sqlMobile.SqlCeConnection mDB = new sqlMobile.SqlCeConnection(Program.mConnectionString);
private Access.OleDbConnection mDB = new Access.OleDbConnection(global::Fleet_Management_System.Properties.Settings.Default.Database);

///
/// Class Constructor
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public cConnect()
{
try
{
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// initializes the connection [opens the database].
/// Only works for my database settings
/// [Note that you can't give a database path]
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
private void sDefaults()
{
try
{
if (global::Fleet_Management_System.Properties.Settings.Default.Database.Length > 5)
{
this.mDB = new Access.OleDbConnection(global::Fleet_Management_System.Properties.Settings.Default.Database);
//this.mDB = new sqlMobile.SqlCeConnection(Program.mConnectionString);

this.mDB.Open();
}
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// This method is used for reading purposes only.
/// NB: Only for reading NOT writing.
/// The database will have a shared lock.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
///
/// SQL statement 2B executed.
///
/// returns a data reader containing the execution
/// results of the sql select statement
///
public Access.OleDbDataReader sRead(string vSQL)
{
Access.OleDbDataReader r = null;
//sqlMobile.SqlCeDataReader r = null;

try
{
if (this.mDB.State != ConnectionState.Open)
this.sDefaults();

//sqlMobile.SqlCeCommand vCMD = new sqlMobile.SqlCeCommand(vSQL, this.mDB);
Access.OleDbCommand vCMD = new Access.OleDbCommand(vSQL, this.mDB);
r = vCMD.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
return r;
}

///
/// This method is used to update/insert/delete
/// records using the appropriate SQL Statements.
/// The database will have an exclusive lock.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
///
/// SQL Statement 2B executed
public void sExecute(string vSQL)
{
DataSet vDS = new DataSet();

try
{
vDS.EnforceConstraints = true;

if (this.mDB.State != ConnectionState.Open)
this.sDefaults();

//sqlMobile.SqlCeDataAdapter vDA = new sqlMobile.SqlCeDataAdapter(vSQL, Program.mConnectionString);
Access.OleDbDataAdapter vDA = new Access.OleDbDataAdapter(vSQL, global::Fleet_Management_System.Properties.Settings.Default.Database);

vDA.AcceptChangesDuringFill = true;
vDA.Fill(vDS);
}
catch (Exception)
{
vDS.RejectChanges();
vDS.Dispose();
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}
}//end of cConnect

///
/// Create, Backup and Restore the physical database
/// It inherits the database connection class
/// This Class has been sealed against modifications via inheritance.
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public sealed class cDatabase : cConnect
{
///
/// class constructor
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
public cDatabase()
{
try
{
System.IO.FileInfo vFL=new FileInfo("App_Data\\Price List.mdb");
if (vFL.Exists)
{
//sqlMobile.SqlCeEngine vEng = new System.Data.SqlServerCe.SqlCeEngine(Program.mConnectionString);

//vEng.CreateDatabase();

//this.sSetEntities();
}
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// create all the entities
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
private void sSetEntities()
{
try
{
sProducts();
sPrices();
sDefaults();
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// create table Products;
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
private void sProducts()
{
try
{
string vSQL;

//CREATE NEW TABLE - Products
vSQL = "CREATE TABLE Products(";
//vSQL += " [vIndex] IDENTITY (1,1),";//Left parameter is for initial value; Right parameter is for incremental value
vSQL += " [Product ID] integer NOT NULL,";
vSQL += " [Description] string(50) NOT NULL,";
vSQL += " PRIMARY KEY ([Product ID])";
vSQL += ");";
//base.sExecute(vSQL);
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// create table Prices;
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
private void sPrices()
{
try
{
string vSQL;

//CREATE NEW TABLE - Prices
vSQL = "CREATE TABLE Prices(";
//vSQL += " [vIndex] IDENTITY (1,1),";//Left parameter is for initial value; Right parameter is for incremental value
vSQL += " [Product ID] integer NOT NULL,";
vSQL += " [Amount] currency NOT NULL,";

vSQL += " FOREIGN KEY ([Product ID]) REFERENCES Products";
vSQL += " ON UPDATE CASCADE";
vSQL += " ON DELETE CASCADE";
//vSQL += " ON DELETE SET NULL";
vSQL += ");";

//base.sExecute(vSQL);
}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

///
/// create default records;
///
/// Designed by: Ogolla Onyango Fredrick -
/// Final year project - CS 282 - 0515/02
///
private void sDefaults()
{
try
{
string vSQL;

vSQL = "INSERT INTO Products([Product ID], [Description]) VALUES(";
vSQL += " 1, 'KASUKU 1');";
base.sExecute(vSQL);

vSQL = "INSERT INTO Products([Product ID], [Description]) VALUES(";
vSQL += " 2, 'KASUKU 2');";
base.sExecute(vSQL);

vSQL = "INSERT INTO Products([Product ID], [Description]) VALUES(";
vSQL += " 3, 'KASUKU 3');";
base.sExecute(vSQL);

vSQL = "INSERT INTO Products([Product ID], [Description]) VALUES(";
vSQL += " 4, 'KASUKU 4');";
base.sExecute(vSQL);

vSQL = "INSERT INTO Products([Product ID], [Description]) VALUES(";
vSQL += " 5, 'KASUKU 5');";
base.sExecute(vSQL);

vSQL = "INSERT INTO Prices([Product ID], [Amount]) VALUES(";
vSQL += " 1, 10);";
base.sExecute(vSQL);

vSQL = "INSERT INTO Prices([Product ID], [Amount]) VALUES(";
vSQL += " 2, 20);";
base.sExecute(vSQL);

vSQL = "INSERT INTO Prices([Product ID], [Amount]) VALUES(";
vSQL += " 3, 30);";
base.sExecute(vSQL);

vSQL = "INSERT INTO Prices([Product ID], [Amount]) VALUES(";
vSQL += " 4, 40);";
base.sExecute(vSQL);

vSQL = "INSERT INTO Prices([Product ID], [Amount]) VALUES(";
vSQL += " 5, 50);";
base.sExecute(vSQL);

}
catch (Exception)
{
throw; /* bubble the error to the active document,
* where the error is caught and resolved */
}
}

}

}

Computing.Net: Awaiting Replies (Database Forum)

Followers