|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionWhile going through lot of articles on MSDN and on other sites, I wasn't able to get enough information in one go. So, I thought to write up an article which will cover up all the cryptography and that too with an example. DescriptionThe .NET Framework provides the following classes that implement:
Till now we have studied a lot about the Cryptography and the support given in .NET Framework 1.1. Let's take up a example for Encryption/Decryption of text. Following is the Code of Encryption with “Rijndael” Algorithm. This is a class library developed in C#. You can use this code as a plug-in and use it for Encryption, Decryption and Hashing. using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Diagnostics;
namespace JackTheGreat.Encryption.Cryptography
{
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Diagnostics;
namespace JackTheGreat.Encryption.Cryptography
{
/// <summary>
/// Summary description for EncryptData.
/// </summary>
public class CryptoLib
{
public System.Security.Cryptography.SymmetricAlgorithm mCryptProv;
public System.Diagnostics.EventLog objEventLog;
#region "Encrypt Function"
public string Encrypt(string EncryptProvider, string EncryptStr,
int BlckSize, int KySize, string Key, string IV)
{
//Check if something Algo is Selected
if(EncryptProvider.Length<=0)
{
return("Pass an Algo to use to Encrypt.");
}
//Since, The selected algo may not be Symmetric, So Try it
try
{
mCryptProv = SymmetricAlgorithm.Create(EncryptProvider);
mCryptProv.Mode = CipherMode.CBC;
}
catch(Exception ee)
{
return("Exception : " + ee.Message);
}
try
{
//Each Algo has different Size of Key and Block, So let's try
mCryptProv.BlockSize = BlckSize;
mCryptProv.KeySize = KySize;
}
catch
{
//Invalid Block or Key Size. Show the Default Ones
string mStr;
mStr = mCryptProv.BlockSize.ToString();
mStr += "Invalid Block or Key Size.Valid Sizes are : ";
mStr += "Block Size = " +
mCryptProv.LegalBlockSizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalBlockSizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalBlockSizes[0].SkipSize.ToString();
mStr += "Key Size = " +
mCryptProv.LegalKeySizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalKeySizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalKeySizes[0].SkipSize.ToString();
return(mStr);
//Show the Valid Block Size
}
try
{
//Change the supplied key to a byte array
byte[] thisKey = stringtoByte(Key,KySize);
//Hash the Supplied Secret key
byte[] resultKey = HashOfByteArray(thisKey);
int loopTill=0;
if(BlckSize==128)loopTill=16;
if(BlckSize==192)loopTill=24;
if(BlckSize==256)loopTill=32;
byte[] BlockKey = new byte[loopTill];
for(int loop=0; loop<loopTill; loop++ )
BlockKey[loop] = resultKey[loop];
//Change the supplied IV to a byte array
byte[] thisIV = stringtoByte(IV,BlckSize);
//Hash the Supplied IV
byte[] resultIV = HashOfByteArray(thisIV);
//byte[] resultIV = thisIV;
byte[] BlockIV = new byte[loopTill];
for( int loop=0; loop<loopTill; loop++ )
BlockIV[loop] = resultIV[loop];
//Create the Encryptor, Passing that the Key and IV
ICryptoTransform mEncryptor =
mCryptProv.CreateEncryptor(BlockKey, BlockIV);
//Create Memory Stream
System.IO.MemoryStream mMemStr = new MemoryStream();
//Create the Crypto Stream,
// Passing that the Memory Stream and Encryptor
CryptoStream mCryptStr= new CryptoStream(mMemStr,
mEncryptor, CryptoStreamMode.Write);
//Convert the Supplied plaintext into a byte array
byte[] bInput = stringtoByte(EncryptStr,512);
//System.Text.Encoding.UTF8.GetBytes(EncryptStr);
//stringtoByte(EncryptStr,512);
// write out encrypted content into MemoryStream
mCryptStr.Write(bInput, 0, bInput.Length);
mCryptStr.FlushFinalBlock();
// get the output and trim the '\0' bytes
byte[] bOutput = mMemStr.GetBuffer();
int MemLength = System.Convert.ToInt32(mMemStr.Length);
//Clean up the memory
mCryptStr.Close();
mMemStr.Close();
mEncryptor.Dispose();
// convert into Base64 so that the result can be used in xml
return Convert.ToBase64String(bOutput,0,MemLength);
}
catch(System.Security.Cryptography.CryptographicException ee)
{
objEventLog = new System.Diagnostics.EventLog();
objEventLog.Source = "SMP-CryptoGraphy";
objEventLog.WriteEntry("Exception Occured in Encryption Process." +
" Error is = " +
ee.Message ,System.Diagnostics.EventLogEntryType.Error);
objEventLog.Dispose();
return("");
}
}
#endregion
#region "Decrypt Function"
public string Decrypt(string EncryptProvider, string EncryptStr,
int BlckSize, int KySize, string Key, string IV)
{
//Check if something Algo is Selected
if(EncryptProvider.Length<=0)
{
return("Pass an Algo to use to Encrypt.");
}
//Since, The selected algo may not be Symmetric, So Try it
try
{
mCryptProv = SymmetricAlgorithm.Create(EncryptProvider);
mCryptProv.Mode = CipherMode.CBC;
}
catch(Exception ee)
{
return("Exception-1: " + ee.Message);
}
try
{
//Each Algo has different Size of Key and Block, So let's try
mCryptProv.BlockSize = BlckSize;
mCryptProv.KeySize = KySize;
}
catch
{
//Invalid Block or Key Size. Show the Default Ones
string mStr;
mStr = mCryptProv.BlockSize.ToString();
mStr += "Invalid Block or Key Size.Valid Sizes are : ";
mStr += "Block Size = " +
mCryptProv.LegalBlockSizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalBlockSizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalBlockSizes[0].SkipSize.ToString();
mStr += "Key Size = " +
mCryptProv.LegalKeySizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalKeySizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalKeySizes[0].SkipSize.ToString();
return(mStr);
//Show the Valid Block Size
}
try
{
//Change the supplied key to a byte array
byte[] thisKey = stringtoByte(Key,KySize);
//Hash the Supplied Secret key
byte[] resultKey = HashOfByteArray(thisKey);
int loopTill=0;
if(BlckSize==128)loopTill=16;
if(BlckSize==192)loopTill=24;
if(BlckSize==256)loopTill=32;
byte[] BlockKey = new byte[loopTill];
for(int loop=0; loop<loopTill; loop++ )
BlockKey[loop] = resultKey[loop];
//Change the supplied IV to a byte array
byte[] thisIV = stringtoByte(IV,BlckSize);
//Hash the Supplied IV
byte[] resultIV = HashOfByteArray(thisIV);
byte[] BlockIV = new byte[loopTill];
for( int loop=0; loop<loopTill; loop++ )
BlockIV[loop] = resultIV[loop];
//Try to Decrypt values in the memory
//First Create the Decryptor, By Passing Key and IV
ICryptoTransform mDecrypt =
mCryptProv.CreateDecryptor(thisKey, thisIV);
byte[] bInput = System.Convert.FromBase64String(EncryptStr);
// create a MemoryStream with the input
System.IO.MemoryStream ms =
new System.IO.MemoryStream(bInput, 0, bInput.Length);
//Create Crypto Stream
CryptoStream mCSReader =
new CryptoStream(ms, mDecrypt, CryptoStreamMode.Read);
// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader(mCSReader);
//Close the crypto stream
mCSReader.Close();
ms.Close();
mDecrypt.Dispose();
return sr.ReadToEnd();
}
catch(System.Exception ee)
{
return("Exception in processing " + ee.Message);
}
}
#endregion
#region "Hashing of a BYTE Array by using SHA512Managed -" +
" return value is a Byte Array"
private byte[] HashOfByteArray(byte[] ByteArray)
{
SHA512Managed sha512Key = new SHA512Managed();
Sha512Key.ComputeHash(ByteArray);
return(sha512Key.Hash);
}
#endregion
#region "Hashing of a String by using SHA512Managed - " +
"return value is a Base64 string"
public string HashOfString(string PlainText)
{
//Change the supplied string to a byte array
try
{
int thisSize = PlainText.Length*8;
int temp;
if(PlainText.Length<1)
{
return("Please enter a Valid String to Hash. String passed is " +
PlainText.ToString());
}
byte[] thisStr = new byte[thisSize];
int lastBound = PlainText.Length;
if(lastBound > thisSize)lastBound = thisSize;
for(temp = 0;temp<=lastBound - 1;temp++)
{
thisStr[temp] = Convert.ToByte(PlainText[temp]);
}
SHA512Managed sha512Key = new SHA512Managed();
Sha512Key.ComputeHash(thisStr);
return(Convert.ToBase64String(sha512Key.Hash));
}
catch(System.Security.Cryptography.CryptographicException ee)
{
return("Exception Occured in Hashing Process. Error is = " +
ee.Message);
}
}
#endregion
#region "String to a byte array conversion -" +
" return value is a BYTE array"
private byte[] stringtoByte(string textdata,int keySize)
{
int thisSize = (keySize / 8);
int temp;
byte[] returnByteArray = new byte[thisSize];
int lastBound = textdata.Length;
if(lastBound > thisSize)lastBound = thisSize;
for(temp = 0;temp<=lastBound - 1;temp++)
{
returnByteArray[temp] = Convert.ToByte(textdata[temp]);
}
return(returnByteArray);
}
#endregion
}
}
/// <summary>
/// Summary description for EncryptData.
/// </summary>
public class CryptoLib
{
public System.Security.Cryptography.SymmetricAlgorithm mCryptProv;
public System.Diagnostics.EventLog objEventLog;
#region "Encrypt Function"
public string Encrypt(string EncryptProvider, string EncryptStr,
int BlckSize, int KySize, string Key, string IV)
{
//Check if something Algo is Selected
if(EncryptProvider.Length<=0)
{
return("Pass an Algo to use to Encrypt.");
}
//Since, The selected algo may not be Symmetric, So Try it
try
{
mCryptProv = SymmetricAlgorithm.Create(EncryptProvider);
mCryptProv.Mode = CipherMode.CBC;
}
catch(Exception ee)
{
return("Exception : " + ee.Message);
}
try
{
//Each Algo has different Size of Key and Block, So let's try
mCryptProv.BlockSize = BlckSize;
mCryptProv.KeySize = KySize;
}
catch
{
//Invalid Block or Key Size. Show the Default Ones
string mStr;
mStr = mCryptProv.BlockSize.ToString();
mStr += "Invalid Block or Key Size.Valid Sizes are : ";
mStr += "Block Size = " +
mCryptProv.LegalBlockSizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalBlockSizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalBlockSizes[0].SkipSize.ToString();
mStr += "Key Size = " +
mCryptProv.LegalKeySizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalKeySizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalKeySizes[0].SkipSize.ToString();
return(mStr);
//Show the Valid Block Size
}
try
{
//Change the supplied key to a byte array
byte[] thisKey = stringtoByte(Key,KySize);
//Hash the Supplied Secret key
byte[] resultKey = HashOfByteArray(thisKey);
int loopTill=0;
if(BlckSize==128)loopTill=16;
if(BlckSize==192)loopTill=24;
if(BlckSize==256)loopTill=32;
byte[] BlockKey = new byte[loopTill];
for(int loop=0; loop<loopTill; loop++ )
BlockKey[loop] = resultKey[loop];
//Change the supplied IV to a byte array
byte[] thisIV = stringtoByte(IV,BlckSize);
//Hash the Supplied IV
byte[] resultIV = HashOfByteArray(thisIV);
//byte[] resultIV = thisIV;
byte[] BlockIV = new byte[loopTill];
for( int loop=0; loop<loopTill; loop++ )
BlockIV[loop] = resultIV[loop];
//Create the Encryptor, Passing that the Key and IV
ICryptoTransform mEncryptor =
mCryptProv.CreateEncryptor(BlockKey, BlockIV);
//Create Memory Stream
System.IO.MemoryStream mMemStr = new MemoryStream();
//Create the Crypto Stream,
//Passing that the Memory Stream and Encryptor
CryptoStream mCryptStr=
new CryptoStream(mMemStr, mEncryptor, CryptoStreamMode.Write);
//Convert the Supplied plaintext into a byte array
byte[] bInput = stringtoByte(EncryptStr,512);
//System.Text.Encoding.UTF8.GetBytes(EncryptStr);
//stringtoByte(EncryptStr,512);
// write out encrypted content into MemoryStream
mCryptStr.Write(bInput, 0, bInput.Length);
mCryptStr.FlushFinalBlock();
// get the output and trim the '\0' bytes
byte[] bOutput = mMemStr.GetBuffer();
int MemLength = System.Convert.ToInt32(mMemStr.Length);
//Clean up the memory
mCryptStr.Close();
mMemStr.Close();
mEncryptor.Dispose();
// convert into Base64 so that the result can be used in xml
return Convert.ToBase64String(bOutput,0,MemLength);
}
catch(System.Security.Cryptography.CryptographicException ee)
{
objEventLog = new System.Diagnostics.EventLog();
objEventLog.Source = "SMP-CryptoGraphy";
objEventLog.WriteEntry("Exception Occured in Encryption " +
"Process. Error is = " + ee.Message,
System.Diagnostics.EventLogEntryType.Error);
objEventLog.Dispose();
return("");
}
}
#endregion
#region "Decrypt Function"
public string Decrypt(string EncryptProvider, string EncryptStr,
int BlckSize, int KySize, string Key, string IV)
{
//Check if something Algo is Selected
if(EncryptProvider.Length<=0)
{
return("Pass an Algo to use to Encrypt.");
}
//Since, The selected algo may not be Symmetric, So Try it
try
{
mCryptProv = SymmetricAlgorithm.Create(EncryptProvider);
mCryptProv.Mode = CipherMode.CBC;
}
catch(Exception ee)
{
return("Exception-1: " + ee.Message);
}
try
{
//Each Algo has different Size of Key and Block, So let's try
mCryptProv.BlockSize = BlckSize;
mCryptProv.KeySize = KySize;
}
catch
{
//Invalid Block or Key Size. Show the Default Ones
string mStr;
mStr = mCryptProv.BlockSize.ToString();
mStr += "Invalid Block or Key Size.Valid Sizes are : ";
mStr += "Block Size = " +
mCryptProv.LegalBlockSizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalBlockSizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalBlockSizes[0].SkipSize.ToString();
mStr += "Key Size = " +
mCryptProv.LegalKeySizes[0].MinSize.ToString() +
" - " + mCryptProv.LegalKeySizes[0].MaxSize.ToString() +
" With Increment of " +
mCryptProv.LegalKeySizes[0].SkipSize.ToString();
return(mStr);
//Show the Valid Block Size
}
try
{
//Change the supplied key to a byte array
byte[] thisKey = stringtoByte(Key,KySize);
//Hash the Supplied Secret key
byte[] resultKey = HashOfByteArray(thisKey);
int loopTill=0;
if(BlckSize==128)loopTill=16;
if(BlckSize==192)loopTill=24;
if(BlckSize==256)loopTill=32;
byte[] BlockKey = new byte[loopTill];
for(int loop=0; loop<loopTill; loop++ )
BlockKey[loop] = resultKey[loop];
//Change the supplied IV to a byte array
byte[] thisIV = stringtoByte(IV,BlckSize);
//Hash the Supplied IV
byte[] resultIV = HashOfByteArray(thisIV);
byte[] BlockIV = new byte[loopTill];
for( int loop=0; loop<loopTill; loop++ )
BlockIV[loop] = resultIV[loop];
//Try to Decrypt values in the memory
//First Create the Decryptor, By Passing Key and IV
ICryptoTransform mDecrypt =
mCryptProv.CreateDecryptor(thisKey, thisIV);
byte[] bInput = System.Convert.FromBase64String(EncryptStr);
// create a MemoryStream with the input
System.IO.MemoryStream ms =
new System.IO.MemoryStream(bInput, 0, bInput.Length);
//Create Crypto Stream
CryptoStream mCSReader =
new CryptoStream(ms, mDecrypt, CryptoStreamMode.Read);
// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader(mCSReader);
//Close the crypto stream
mCSReader.Close();
ms.Close();
mDecrypt.Dispose();
return sr.ReadToEnd();
}
catch(System.Exception ee)
{
return("Exception in processing " + ee.Message);
}
}
#endregion
#region "Hashing of a BYTE Array by using SHA512Managed -" +
" return value is a Byte Array"
private byte[] HashOfByteArray(byte[] ByteArray)
{
SHA512Managed sha512Key = new SHA512Managed();
Sha512Key.ComputeHash(ByteArray);
return(sha512Key.Hash);
}
#endregion
#region "Hashing of a String by using SHA512Managed - " +
"return value is a Base64 string"
public string HashOfString(string PlainText)
{
//Change the supplied string to a byte array
try
{
int thisSize = PlainText.Length*8;
int temp;
if(PlainText.Length<1)
{
return("Please enter a Valid String to Hash. String passed is " +
PlainText.ToString());
}
byte[] thisStr = new byte[thisSize];
int lastBound = PlainText.Length;
if(lastBound > thisSize)lastBound = thisSize;
for(temp = 0;temp<=lastBound - 1;temp++)
{
thisStr[temp] = Convert.ToByte(PlainText[temp]);
}
SHA512Managed sha512Key = new SHA512Managed();
Sha512Key.ComputeHash(thisStr);
return(Convert.ToBase64String(sha512Key.Hash));
}
catch(System.Security.Cryptography.CryptographicException ee)
{
return("Exception Occured in Hashing Process. Error is = " +
ee.Message);
}
}
#endregion
#region "String to a byte array conversion - " +
"return value is a BYTE array"
private byte[] stringtoByte(string textdata,int keySize)
{
int thisSize = (keySize / 8);
int temp;
byte[] returnByteArray = new byte[thisSize];
int lastBound = textdata.Length;
if(lastBound > thisSize)lastBound = thisSize;
for(temp = 0;temp<=lastBound - 1;temp++)
{
returnByteArray[temp] = Convert.ToByte(textdata[temp]);
}
return(returnByteArray);
}
#endregion
}
}
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||