While 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.
The .NET Framework provides the following classes that implement:
| Algo Name | Algo Class (Abstract) | Valid Key Size (bit) | Default Key Size (Bit) | Default Implementation Class |
| DES | DES | 64 | 64 | DESCryptoServiceProvider |
| TripleDES | TripleDES | 128, 192 | 192 | TripleDESCryptoServiceProvider |
| RC2 | RC2 | 40-128 | 128 | RC2CryptoServiceProvider |
| RijnDael | RijnDael | 128, 192, 256 | 256 | RijnDaelManaged |
Any change to the data or the HMAC will result in a mismatch, because knowledge of the secret key is required to change the message and reproduce the correct HMAC. Therefore, if the codes match, the message is authenticated.
HMACSHA1 accepts keys of any size, and produces a hash sequence of length 20 bytes.
Any change to the data or the MAC will result in a mismatch, because knowledge of the secret key is required to change the message and reproduce the correct MAC. Therefore, if the codes match, the message is authenticated.
MACTripleDES uses a key of length 8, 16 or 24 bytes, and produces a hash sequence of length 8 bytes.
This is a purely managed implementation of SHA1 that does not wrap CAPI.
The hash size for the SHA1Managed algorithm is 160 bits.
This is an abstract class. The only implementation of this class is SHA384Managed.
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
}
}
| You must Sign In to use this message board. | |||||||||||||||||||||
|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
|||||||||||||||||||||