Re: DES Key & IV

From: Keith Patrick (richard_keith_patrick_at_nospam.hotmail.com)
Date: 08/07/03


Date: Wed, 6 Aug 2003 23:20:57 -0500


Lemme know how this works out for you (I based this stuff off some code I
found on the net, and I really don't know enough about IVs to implement this
better, but the guts of the crypto works):

#region Public Methods

/// <summary>

/// Encrypts a data stream

/// </summary>

/// <param name="data">The data being encrypted</param>

/// <param name="key">The key used to encrypt the data</param>

/// <returns>The encrypted form of <c>data</c></returns>

public String EncryptData(String data,

String key) {

if ((key == null)

|| (key.Equals(String.Empty))) {

return data; // IMPORTANT: This is how we decrypt data!

}

Byte[] byteKey = GetKey(key);

Byte[] byteIV = GetInitializationVector(key);

string strResult; //Return Result

//1. String Length cannot exceed 90Kb. Otherwise, buffer will overflow. See
point 3 for reasons

if (data.Length > 92160) {

return data;

}

//3. Prepare the String

// The first 5 character of the string is formatted to store the actual
length of the data.

// This is the simplest way to remember to original length of the data,
without resorting to complicated computations.

// If anyone figure a good way to 'remember' the original length to facilite
the decryption without having to use additional function parameters, pls let
me know.

data = String.Format("{0,5:00000}"+data, data.Length);

//4. Encrypt the Data

byte[] rbData = new byte[data.Length];

ASCIIEncoding aEnc = new ASCIIEncoding();

aEnc.GetBytes(data, 0, data.Length, rbData, 0);

ICryptoTransform desEncrypt =
this.CryptoServiceProvider.CreateEncryptor(byteKey, byteIV);

//5. Perpare the streams:

// mOut is the output stream.

// mStream is the input stream.

// cs is the transformation stream.

MemoryStream mStream = new MemoryStream(rbData);

CryptoStream cs = new CryptoStream(mStream, desEncrypt,
CryptoStreamMode.Read);

MemoryStream mOut = new MemoryStream();

//6. Start performing the encryption

int bytesRead;

byte[] output = new byte[1024];

do

{

bytesRead = cs.Read(output,0,1024);

if (bytesRead != 0)

mOut.Write(output,0,bytesRead);

} while (bytesRead > 0);

//7. Returns the encrypted result after it is base64 encoded

// In this case, the actual result is converted to base64 so that it can be
transported over the HTTP protocol without deformation.

if (mOut.Length == 0)

strResult = "";

else

strResult = Convert.ToBase64String(mOut.GetBuffer(), 0, (int)mOut.Length);

return strResult;

}

/// <summary>

/// Decrypts a data stream

/// </summary>

/// <param name="data">The data being decypted</param>

/// <param name="key">The key used to encrypt the data</param>

/// <returns>The decrypted form of <c>data</c></returns>

public String DecryptData(String data,

String key) {

Byte[] byteKey = GetKey(key);

Byte[] byteIV = GetInitializationVector(key);

string strResult;

//2. Initialize the service provider

int nReturn = 0;

ICryptoTransform desDecrypt =
this.CryptoServiceProvider.CreateDecryptor(byteKey, byteIV);

//3. Prepare the streams:

// mOut is the output stream.

// cs is the transformation stream.

MemoryStream mOut = new MemoryStream();

CryptoStream cs = new CryptoStream(mOut, desDecrypt,
CryptoStreamMode.Write);

//4. Remember to revert the base64 encoding into a byte array to restore the
original encrypted data stream

byte[] bPlain = new byte[data.Length];

try {

bPlain = Convert.FromBase64CharArray(data.ToCharArray(), 0, data.Length);

}

catch (Exception) {

return data;

}

long lRead = 0;

long lTotal = data.Length;

try

{

//5. Perform the actual decryption

while (lTotal >= lRead)

{

cs.Write(bPlain,0,(int)bPlain.Length);

//this.CryptoServiceProvider.BlockSize=64

lRead = mOut.Length + Convert.ToUInt32(((bPlain.Length /
this.CryptoServiceProvider.BlockSize) *
this.CryptoServiceProvider.BlockSize));

};

ASCIIEncoding aEnc = new ASCIIEncoding();

strResult = aEnc.GetString(mOut.GetBuffer(), 0, (int)mOut.Length);

//6. Trim the string to return only the meaningful data

// Remember that in the encrypt function, the first 5 character holds the
length of the actual data

// This is the simplest way to remember to original length of the data,
without resorting to complicated computations.

String strLen = strResult.Substring(0,5);

int nLen = Convert.ToInt32(strLen);

strResult = strResult.Substring(5, nLen);

nReturn = (int)mOut.Length;

return strResult;

}

catch {

return data; // In case data is not encrypted yet

}

}

#endregion



Relevant Pages