dxterra
unread,Feb 26, 2009, 11:09:31 AM2/26/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
I have an application that uses CryptoStream to encrypt and decrypt
strings and stores and retrieves these values from a SQLServer
database.
When I run the application on my machine I can decrypt all the strings
in the database. When I run from a server I get "Bad Data" errors when
I try to close my CryptoStream.
Here is a sample application that I threw together:
using System;
using System.Collections;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace myTest
{
class Program
{
private static byte[] byteToken;
static void Main( string[] args )
{
Console.WriteLine( "Decoding sample string:" );
string testtoken = "mGAETZOUuW5tjFR4ihp80D23JQg4Uhtfdq
+UjZlBOE9XIRVvi+FtKg3R7TygdTEOjG+Qj6SLXl24fng+vuubLzK1vX1igECVQV
+9KKDjWpSG82S
+GTVOMsButxrae1bN83XdcFV0TN82iBW3Er4fKFfYSgAwyNEDCtrKO1hbbInLD0Z5ktzNB
+pfU4JVOVKAUbSPjIt4/8Na8HJimxleF6q/0SmRL0EOiyJRMT1xrKSHBK2VY/
rJnMicl053U+J1ZDGcHbUBPY1Z+
+dd0cfgKD79t6N0QJLzyPeuRVjmobT6lxznalAxgp5g0IXQugsMHuWeBR/zl/yey/
+h5dHPoK5XRGs56F+P";
Console.WriteLine( DecryptDES( testtoken ) );
Console.WriteLine( "Creating new string:" );
string tmpToken = EncryptDES( RandomString( 64, 64 ) );
Console.WriteLine( tmpToken );
Console.WriteLine( "Decoding new string:" );
Console.WriteLine( DecryptDES( tmpToken ) );
}
#region Encryption Methods
private static string RandomToken()
{
byte[] randombytes = new byte[128];
RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider
();
Gen.GetBytes( randombytes );
byteToken = randombytes;
return Encoding.Unicode.GetString( randombytes );
}
public static string RandomString( int minLength, int
maxLength )
{
string PASSWORD_CHARS_LCASE = "abcdefgijkmnopqrstwxyz";
string PASSWORD_CHARS_UCASE = "ABCDEFGHJKLMNPQRSTWXYZ";
string PASSWORD_CHARS_NUMERIC = "123456789";
string PASSWORD_CHARS_SPECIAL = "*$-+?_&=!{}";
// Create a local array containing supported password
characters
// grouped by types. You can remove character groups from
this
// array, but doing so will weaken the password strength.
char[][] charGroups = new char[][]
{
PASSWORD_CHARS_LCASE.ToCharArray(),
PASSWORD_CHARS_UCASE.ToCharArray(),
PASSWORD_CHARS_NUMERIC.ToCharArray(),
PASSWORD_CHARS_SPECIAL.ToCharArray()
};
// Use this array to track the number of unused characters
in each
// character group.
int[] charsLeftInGroup = new int[charGroups.Length];
// Initially, all characters in each group are not used.
for( int i = 0; i < charsLeftInGroup.Length; i++ )
charsLeftInGroup[i] = charGroups[i].Length;
// Use this array to track (iterate through) unused
character groups.
int[] leftGroupsOrder = new int[charGroups.Length];
// Initially, all character groups are not used.
for( int i = 0; i < leftGroupsOrder.Length; i++ )
leftGroupsOrder[i] = i;
// Because we cannot use the default randomizer, which is
based on the
// current time (it will produce the same "random" number
within a
// second), we will use a random number generator to seed
the
// randomizer.
// Use a 4-byte array to fill it with random bytes and
convert it then
// to an integer value.
byte[] randomBytes = new byte[4];
// Generate 4 random bytes.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider
();
rng.GetBytes( randomBytes );
// Convert 4 bytes into a 32-bit integer value.
int seed = ( randomBytes[0] & 0x7f ) << 24 |
randomBytes[1] << 16 |
randomBytes[2] << 8 |
randomBytes[3];
// Now, this is real randomization.
Random random = new Random( seed );
// This array will hold password characters.
char[] password = null;
// Allocate appropriate memory for the password.
if( minLength < maxLength )
password = new char[random.Next( minLength, maxLength
+ 1 )];
else
password = new char[minLength];
// Index of the next character to be added to password.
int nextCharIdx;
// Index of the next character group to be processed.
int nextGroupIdx;
// Index which will be used to track not processed
character groups.
int nextLeftGroupsOrderIdx;
// Index of the last non-processed character in a group.
int lastCharIdx;
// Index of the last non-processed group.
int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
// Generate password characters one at a time.
for( int i = 0; i < password.Length; i++ )
{
// If only one character group remained unprocessed,
process it;
// otherwise, pick a random character group from the
unprocessed
// group list. To allow a special character to appear
in the
// first position, increment the second parameter of
the Next
// function call by one, i.e. lastLeftGroupsOrderIdx +
1.
if( lastLeftGroupsOrderIdx == 0 )
nextLeftGroupsOrderIdx = 0;
else
nextLeftGroupsOrderIdx = random.Next( 0,
lastLeftGroupsOrderIdx );
// Get the actual index of the character group, from
which we will
// pick the next character.
nextGroupIdx = leftGroupsOrder
[nextLeftGroupsOrderIdx];
// Get the index of the last unprocessed characters in
this group.
lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;
// If only one unprocessed character is left, pick it;
otherwise,
// get a random character from the unused character
list.
if( lastCharIdx == 0 )
nextCharIdx = 0;
else
nextCharIdx = random.Next( 0, lastCharIdx + 1 );
// Add this character to the password.
password[i] = charGroups[nextGroupIdx][nextCharIdx];
// If we processed the last character in this group,
start over.
if( lastCharIdx == 0 )
charsLeftInGroup[nextGroupIdx] = charGroups
[nextGroupIdx].Length;
// There are more unprocessed characters left.
else
{
// Swap processed character with the last
unprocessed character
// so that we don't pick it until we process all
characters in
// this group.
if( lastCharIdx != nextCharIdx )
{
char temp = charGroups[nextGroupIdx]
[lastCharIdx];
charGroups[nextGroupIdx][lastCharIdx] =
charGroups[nextGroupIdx][nextCharIdx];
charGroups[nextGroupIdx][nextCharIdx] = temp;
}
// Decrement the number of unprocessed characters
in
// this group.
charsLeftInGroup[nextGroupIdx]--;
}
// If we processed the last group, start all over.
if( lastLeftGroupsOrderIdx == 0 )
lastLeftGroupsOrderIdx = leftGroupsOrder.Length -
1;
// There are more unprocessed groups left.
else
{
// Swap processed group with the last unprocessed
group
// so that we don't pick it until we process all
groups.
if( lastLeftGroupsOrderIdx !=
nextLeftGroupsOrderIdx )
{
int temp = leftGroupsOrder
[lastLeftGroupsOrderIdx];
leftGroupsOrder[lastLeftGroupsOrderIdx] =
leftGroupsOrder[nextLeftGroupsOrderIdx];
leftGroupsOrder[nextLeftGroupsOrderIdx] =
temp;
}
// Decrement the number of unprocessed groups.
lastLeftGroupsOrderIdx--;
}
}
// Convert password characters into a string and return
the result.
return new string( password );
}
public static byte[] EncryptDES( byte[] clearData, byte[] Key,
byte[] IV )
{
MemoryStream ms = new MemoryStream();
TripleDES tripDES = TripleDES.Create();
tripDES.Key = Key;
tripDES.IV = IV;
CryptoStream cs = new CryptoStream( ms,
tripDES.CreateEncryptor(), CryptoStreamMode.Write );
cs.Write( clearData, 0, clearData.Length );
cs.Close();
ms.Close();
byte[] encryptedData = ms.ToArray();
byte[] testbyte = new byte[byteToken.Length +
encryptedData.Length];
byteToken.CopyTo( testbyte, 0 );
encryptedData.CopyTo( testbyte, byteToken.Length );
return testbyte;
}
public static string EncryptDES( string clearText )
{
byte[] clearBytes = Encoding.Unicode.GetBytes
( clearText );
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes
( RandomToken(),
new byte[] { 0xe3, 0xe4, 0xed, 0x43, 0x6e, 0x74, 0x72,
0x61, 0x2e, 0x6d, 0x65, 0x6c,
0x4c, 0x6f, 0x6e, 0x62, 0x41, 0x4e,
0x6b, 0x2e, 0x43,
0x6f, 0x6d, 0x5c, 0x52, 0x50, 0x4e,
0x73, 0x53, 0xe3, 0xe4, 0xed} );
byte[] encryptedData = EncryptDES( clearBytes, pdb.GetBytes
( 24 ), pdb.GetBytes( 8 ) );
return Convert.ToBase64String( encryptedData );
}
#endregion
#region Decryption Methods
private static byte[] DecryptDES( byte[] cipherData, byte[]
Key, byte[] IV )
{
MemoryStream ms = new MemoryStream();
TripleDES tripDES = TripleDES.Create();
tripDES.Key = Key;
tripDES.IV = IV;
CryptoStream cs = new CryptoStream( ms,
tripDES.CreateDecryptor(), CryptoStreamMode.Write );
cs.Write( cipherData, 0, cipherData.Length );
cs.FlushFinalBlock();
cs.Close();
ms.Flush();
ms.Close();
byte[] decryptedData = ms.ToArray();
return decryptedData;
}
public static string DecryptDES( string cipherText )
{
//string ErrorText = "Error: ";
byte[] cipherBytes;
try
{
try
{
cipherBytes = Convert.FromBase64String
( cipherText );
}
catch
{
throw new FormatException();
}
byte[] rmk = new byte[128];
byte[] cipher = new byte[cipherBytes.Length - 128];
int i = 0;
for( i = 0; i < 128; i++ )
{
rmk[i] = cipherBytes[i];
}
int j = 0;
for( i = 0; i < ( cipherBytes.Length - 128 ); i++ )
{
cipher[j] = cipherBytes[i + 128];
j++;
}
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes
( System.Text.Encoding.Unicode.GetString( rmk ),
new byte[] { 0xe3, 0xe4, 0xed, 0x43, 0x6e, 0x74,
0x72, 0x61, 0x2e, 0x6d, 0x65, 0x6c,
0x4c, 0x6f, 0x6e, 0x62, 0x41, 0x4e,
0x6b, 0x2e, 0x43,
0x6f, 0x6d, 0x5c, 0x52, 0x50, 0x4e,
0x73, 0x53, 0xe3, 0xe4, 0xed} );
byte[] decryptedData = DecryptDES( cipher, pdb.GetBytes
( 24 ), pdb.GetBytes( 8 ) );
return Encoding.Unicode.GetString( decryptedData );
}
catch( Exception e )
{
throw new Exception( e.ToString() );
}
}
#endregion
}
}
Any help would be appreciated. Thanks.