String Encryption Help

  • Thread starter Thread starter j1mb0jay
  • Start date Start date
J

j1mb0jay

I have had to create a simple string encryption program for coursework, I
have completed the task and now have to do a write up on how it could be
improved at a later date. If you could look through the code and point me in
the correct direction one would be very grateful.

Example Input : j1mb0jay
Example Output 1 :
rZHKZbYZWn/4UgL9mAjN2DUz7X/UpcpRxXM9SO1QkvkOe5nOPEKnZldpsB7uHUNZ
Example Output 2 :
8SFgIdt0K0GqOggOt5VUzRc+sVtgPPQJt5xen7WksC3SljaXC/H38pWpjZ37tHyY
Example Outout 3 :
an+RFZnhJpyv+UgdViO6SlZtPZ66DzZ1tGFifpq3QkHr9MX9O/JQkojuS2O0IYIG

As seen above I have used the time as a factor when creating the passwords,
so two users with the same password will not have the same hash stored in
the database.

public string JJEncryption(string password)
{
//Creates a random number generator.
Random random = new Random();
//Creates a random int.
double randomNo = random.NextDouble();
//Turns the double into a number that i can use.
double roundedRandomNo = randomNo * 100;

//Case the double into and int (loosing all decimal places)
int randomInt = (int)roundedRandomNo;

//Gets the current milli second.
int milli = DateTime.Now.Millisecond;

//Convert the milli second and the random int into a string and
add it to an empty string;
string ePassword = ConvertToBase64(milli.ToString()) + "-" +
ConvertToBase64(randomInt.ToString());

//Update the value of milli by adding the random number to it.
milli = milli + randomInt;

//Foreach character in the paratmeter string "password"
foreach (char c in password)
{
//Convert the letter into a number.
int i = Convert.ToInt32(c);
//Add the value of milli to the number representation of the
current letter.
i = i + milli;
//Add this as a string to the return string
ePassword = ePassword + "-" + i.ToString();
}
//Return the enrypted password.
ePassword = MD5Encrypt(ePassword, true);
return ePassword;
}

private string ConvertToBase64(string text)
{
try
{
byte[] enc = new byte[text.Length];
for (int i = 0; i < text.Length; i++)
{
enc = System.Convert.ToByte(text);
}

return System.Convert.ToBase64String(enc);
}
catch
{
}

return string.Empty;
}

//Helped from CodeProject.com
private string MD5Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

// Get the key from config file
string key = ApplicationSettings.MeetySettings.Key;
//System.Windows.Forms.MessageBox.Show(key);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data of the
Cryptographic service provide. Best Practice

hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)

tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0,
resultArray.Length);
}
 
j1mb0jay said:
I have had to create a simple string encryption program for coursework,
I have completed the task and now have to do a write up on how it could
be improved at a later date. If you could look through the code and
point me in the correct direction one would be very grateful.

Example Input : j1mb0jay
Example Output 1 :
rZHKZbYZWn/4UgL9mAjN2DUz7X/UpcpRxXM9SO1QkvkOe5nOPEKnZldpsB7uHUNZ
Example Output 2 :
8SFgIdt0K0GqOggOt5VUzRc+sVtgPPQJt5xen7WksC3SljaXC/H38pWpjZ37tHyY
Example Outout 3 :
an+RFZnhJpyv+UgdViO6SlZtPZ66DzZ1tGFifpq3QkHr9MX9O/JQkojuS2O0IYIG

As seen above I have used the time as a factor when creating the
passwords, so two users with the same password will not have the same
hash stored in the database.

Some reflections:

:: Use a StringBuilder when concatenating the string. Your solution
scales very badly.

:: Hashing is not encryption. MD5Encrypt is a misleading name, as MD5 is
a hashing algorithm and doesn't do any encryption at all.

:: If the task was to actually create encryption, you have not completed
it. As you are using a hash, the string can not be decrypted into the
original string.
 
Göran Andersson said:
Some reflections:

a hashing algorithm and doesn't do any encryption at all.

it. As you are using a hash, the string can not be decrypted into the
original string.

I have the methods to turn it back into the orignal and i use them on my
applications.
Does this mean i am encrypting ?

Thank you for the reply.
 
Hi... It looks a bit overly complex to me but I'll assume it is doing what
you intend. I'd make the suggestion that you simplify the process where
possible however. From the look of it many of the interim values aren't
really used anywhere (though I may have missed it) so you can probably get
your random integer var set this way.
Random random = new Random();
int randomInt = (int) ( random.NextDouble() * 100 );

And the various additions and concatenations can use the += operator so
these:
milli = milli + randomInt;
i = i + milli;
ePassword = ePassword + "-" + i.ToString();
become:
milli += randomInt;
i += milli;
ePassword += ( "-" + i.ToString() );

As Göran points out you may want to use a StringBuilder as well.

I guess if I had a question it would be is there slightly less complicated
way to get the non-matching hash if that is your goal? Do you consider it
more secure by virtue of the particular algorithm used to adjust it?


j1mb0jay said:
I have had to create a simple string encryption program for coursework, I
have completed the task and now have to do a write up on how it could be
improved at a later date. If you could look through the code and point me
in the correct direction one would be very grateful.

Example Input : j1mb0jay
Example Output 1 :
rZHKZbYZWn/4UgL9mAjN2DUz7X/UpcpRxXM9SO1QkvkOe5nOPEKnZldpsB7uHUNZ
Example Output 2 :
8SFgIdt0K0GqOggOt5VUzRc+sVtgPPQJt5xen7WksC3SljaXC/H38pWpjZ37tHyY
Example Outout 3 :
an+RFZnhJpyv+UgdViO6SlZtPZ66DzZ1tGFifpq3QkHr9MX9O/JQkojuS2O0IYIG

As seen above I have used the time as a factor when creating the
passwords, so two users with the same password will not have the same hash
stored in the database.

public string JJEncryption(string password)
{
//Creates a random number generator.
Random random = new Random();
//Creates a random int.
double randomNo = random.NextDouble();
//Turns the double into a number that i can use.
double roundedRandomNo = randomNo * 100;

//Case the double into and int (loosing all decimal places)
int randomInt = (int)roundedRandomNo;

//Gets the current milli second.
int milli = DateTime.Now.Millisecond;

//Convert the milli second and the random int into a string and
add it to an empty string;
string ePassword = ConvertToBase64(milli.ToString()) + "-" +
ConvertToBase64(randomInt.ToString());

//Update the value of milli by adding the random number to it.
milli = milli + randomInt;

//Foreach character in the paratmeter string "password"
foreach (char c in password)
{
//Convert the letter into a number.
int i = Convert.ToInt32(c);
//Add the value of milli to the number representation of
the current letter.
i = i + milli;
//Add this as a string to the return string
ePassword = ePassword + "-" + i.ToString();
}
//Return the enrypted password.
ePassword = MD5Encrypt(ePassword, true);
return ePassword;
}

private string ConvertToBase64(string text)
{
try
{
byte[] enc = new byte[text.Length];
for (int i = 0; i < text.Length; i++)
{
enc = System.Convert.ToByte(text);
}

return System.Convert.ToBase64String(enc);
}
catch
{
}

return string.Empty;
}

//Helped from CodeProject.com
private string MD5Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

// Get the key from config file
string key = ApplicationSettings.MeetySettings.Key;
//System.Windows.Forms.MessageBox.Show(key);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data of the
Cryptographic service provide. Best Practice

hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)

tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0,
resultArray.Length);
}
 
Tom said:
Hi... It looks a bit overly complex to me but I'll assume it is doing
what you intend. I'd make the suggestion that you simplify the
process where possible however. From the look of it many of the
interim values aren't really used anywhere (though I may have missed
it) so you can probably get your random integer var set this way.


And the various additions and concatenations can use the += operator
so these:

As Göran points out you may want to use a StringBuilder as well.

I guess if I had a question it would be is there slightly less
complicated way to get the non-matching hash if that is your goal? Do you
consider it more secure by virtue of the particular algorithm
used to adjust it?

I do understand the code could do with a good tidy up, thank you for the
methods of doing this. I hope when I shorten the methods and use more
correct
coding constructs it will become less complex to read.

We had to write a simple encryption method and decryption method for the
coursework, I just wanted to try and use MD5 and base64 to turn the output
of the encryption into something a little less readable. Was I incorrect in
doing this ?
I thought it would be for the greater good of the encryption !
 
I have had to create a simple string encryption program for coursework, I
have completed the task and now have to do a write up on how it could be
improved at a later date. If you could look through the code and point me in
the correct direction one would be very grateful.

Example Input : j1mb0jay
Example Output 1 :
rZHKZbYZWn/4UgL9mAjN2DUz7X/UpcpRxXM9SO1QkvkOe5nOPEKnZldpsB7uHUNZ
Example Output 2 :
8SFgIdt0K0GqOggOt5VUzRc+sVtgPPQJt5xen7WksC3SljaXC/H38pWpjZ37tHyY
Example Outout 3 :
an+RFZnhJpyv+UgdViO6SlZtPZ66DzZ1tGFifpq3QkHr9MX9O/JQkojuS2O0IYIG

As seen above I have used the time as a factor when creating the passwords,
so two users with the same password will not have the same hash stored in
the database.

public string JJEncryption(string password)
{
//Creates a random number generator.
Random random = new Random();
Random is not cryptographically secure. For a cryptographically
secure PRNG use System.Security.Cryptography.RandomNumberGenerator
Alternatively, write your own - google 'Yarrow' or 'Fortuna' for
examples.

//Creates a random int.
double randomNo = random.NextDouble();
//Turns the double into a number that i can use.
double roundedRandomNo = randomNo * 100;

//Case the double into and int (loosing all decimal places)
int randomInt = (int)roundedRandomNo;

//Gets the current milli second.
int milli = DateTime.Now.Millisecond;

//Convert the milli second and the random int into a string and
add it to an empty string;
string ePassword = ConvertToBase64(milli.ToString()) + "-" +
ConvertToBase64(randomInt.ToString());

//Update the value of milli by adding the random number to it.
milli = milli + randomInt;

//Foreach character in the paratmeter string "password"
foreach (char c in password)
{
//Convert the letter into a number.
int i = Convert.ToInt32(c);
//Add the value of milli to the number representation of the
current letter.
i = i + milli;
//Add this as a string to the return string
ePassword = ePassword + "-" + i.ToString();
}
//Return the enrypted password.
ePassword = MD5Encrypt(ePassword, true);
return ePassword;
Have a look at using System.Security.SecureString instead of a plain
string for holding a password.
}

private string ConvertToBase64(string text)
{
try
{
byte[] enc = new byte[text.Length];
for (int i = 0; i < text.Length; i++)
{
enc = System.Convert.ToByte(text);
}

return System.Convert.ToBase64String(enc);
}
catch
{
}

return string.Empty;
}

You can use Encoding.UTF8.GetBytes to convert a string to bytes.

//Helped from CodeProject.com
private string MD5Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

// Get the key from config file
string key = ApplicationSettings.MeetySettings.Key;
//System.Windows.Forms.MessageBox.Show(key);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new
MD5 should not be used in new applicatins as it has some weaknesses.
Better to use SHA-256 or SHA-512.
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data of the
Cryptographic service provide. Best Practice

hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
3DES should not be used except for backwards compatibility - its 64
bit blocksize is too small for safety. Use AES (=Rijndael) instead as
it uses 128 bit blocks.
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
A bad choice. ECB mode leaks information. For a good illustration
(literally) see
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

You should use either CBC or CTR mode.


//padding mode(if any extra byte added)

tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0,
resultArray.Length);
}
 
rossum said:
I have had to create a simple string encryption program for
coursework, I have completed the task and now have to do a write up
on how it could be improved at a later date. If you could look
through the code and point me in the correct direction one would be
very grateful.

Example Input : j1mb0jay
Example Output 1 :
rZHKZbYZWn/4UgL9mAjN2DUz7X/UpcpRxXM9SO1QkvkOe5nOPEKnZldpsB7uHUNZ
Example Output 2 :
8SFgIdt0K0GqOggOt5VUzRc+sVtgPPQJt5xen7WksC3SljaXC/H38pWpjZ37tHyY
Example Outout 3 :
an+RFZnhJpyv+UgdViO6SlZtPZ66DzZ1tGFifpq3QkHr9MX9O/JQkojuS2O0IYIG

As seen above I have used the time as a factor when creating the
passwords, so two users with the same password will not have the
same hash stored in the database.

public string JJEncryption(string password)
{
//Creates a random number generator.
Random random = new Random();
Random is not cryptographically secure. For a cryptographically
secure PRNG use System.Security.Cryptography.RandomNumberGenerator
Alternatively, write your own - google 'Yarrow' or 'Fortuna' for
examples.

//Creates a random int.
double randomNo = random.NextDouble();
//Turns the double into a number that i can use.
double roundedRandomNo = randomNo * 100;

//Case the double into and int (loosing all decimal
places) int randomInt = (int)roundedRandomNo;

//Gets the current milli second.
int milli = DateTime.Now.Millisecond;

//Convert the milli second and the random int into a
string and add it to an empty string;
string ePassword = ConvertToBase64(milli.ToString()) +
"-" + ConvertToBase64(randomInt.ToString());

//Update the value of milli by adding the random number
to it. milli = milli + randomInt;

//Foreach character in the paratmeter string "password"
foreach (char c in password)
{
//Convert the letter into a number.
int i = Convert.ToInt32(c);
//Add the value of milli to the number representation
of the current letter.
i = i + milli;
//Add this as a string to the return string
ePassword = ePassword + "-" + i.ToString();
}
//Return the enrypted password.
ePassword = MD5Encrypt(ePassword, true);
return ePassword;
Have a look at using System.Security.SecureString instead of a plain
string for holding a password.
}

private string ConvertToBase64(string text)
{
try
{
byte[] enc = new byte[text.Length];
for (int i = 0; i < text.Length; i++)
{
enc = System.Convert.ToByte(text);
}

return System.Convert.ToBase64String(enc);
}
catch
{
}

return string.Empty;
}

You can use Encoding.UTF8.GetBytes to convert a string to bytes.

//Helped from CodeProject.com
private string MD5Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray =
UTF8Encoding.UTF8.GetBytes(toEncrypt);

// Get the key from config file
string key = ApplicationSettings.MeetySettings.Key;
//System.Windows.Forms.MessageBox.Show(key);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new
MD5 should not be used in new applicatins as it has some weaknesses.
Better to use SHA-256 or SHA-512.
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data of the
Cryptographic service provide. Best Practice

hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
3DES should not be used except for backwards compatibility - its 64
bit blocksize is too small for safety. Use AES (=Rijndael) instead as
it uses 128 bit blocks.
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
A bad choice. ECB mode leaks information. For a good illustration
(literally) see
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

You should use either CBC or CTR mode.


//padding mode(if any extra byte added)

tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to
resultArray byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0,
toEncryptArray.Length); //Release resources held by
TripleDes Encryptor tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0,
resultArray.Length);
}


I will post back later with the changes you sugested. Thank you.
 
I have the methods to turn it back into the orignal and i use them on my
applications.
Does this mean i am encrypting ?
You are using MD5 to generate a key from the user password using the
time as salt. The actual encryption uses 3DES.

rossum
 
j1mb0jay said:
I have the methods to turn it back into the orignal and i use them on my
applications.

No, you don't. You can not recreate the original from it's hash code.
 
Göran Andersson said:
:: Hashing is not encryption. MD5Encrypt is a misleading name, as MD5 is
a hashing algorithm and doesn't do any encryption at all.

Some people call hashing "one way encryption".

Arne
 
Arne said:
Some people call hashing "one way encryption".

Arne

Yes. To be strictly correct one would say that hashing can be used as a
one way encryption. The hashing algorithm still does hashing, not
encryption. The difference is subtle, but one should be aware that
hashing serves a different purpose than encryption, so not all hashing
algorthms are well suited for one way encryption.
 
Ok just for you...... since im not planning on using it any where other than
coursework, heres the code to decrypt, try them !!

I assure you they work.


public string JJDycryption(string ePassword)
{

string nonB64password = MD5Decrypt(ePassword,true);

char[] splitter = { '-' };

string[] s = nonB64password.Split(splitter);

int milli = Convert.ToInt32(ConvertFromBase64(s[0]));

int ramdom = Convert.ToInt32(ConvertFromBase64(s[1]));

milli = milli + ramdom;

string password = string.Empty;

for (int index = 2; index < s.Length; index++)

{

int i = Convert.ToInt32(s[index]);

i = i - milli;

char c = Convert.ToChar(i);

password = password + c.ToString();

}

return password;

}

private string MD5Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
//get the byte code of the string

byte[] toEncryptArray = Convert.FromBase64String(cipherString);

System.Configuration.AppSettingsReader settingsReader = new
AppSettingsReader();
//Get your key from config file to open the lock!
string key = ApplicationSettings.MeetySettings.Key;

if (useHashing)
{
//if hashing was used get the hash code with regards to your
key
MD5CryptoServiceProvider hashmd5 = new
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//release any resource held by the MD5CryptoServiceProvider

hashmd5.Clear();
}
else
{
//if hashing was not implemented get the byte code of the
key
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)

tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}

private string ConvertFromBase64(string text)
{
string ret = string.Empty;
byte[] enc = System.Convert.FromBase64String(text);
for (int i = 0; i < enc.Length; i++)
{
ret += System.Convert.ToChar(enc).ToString();
}
return ret;
}

Regards JJ (UWA)
 
Yes. To be strictly correct one would say that hashing can be used as a
one way encryption. The hashing algorithm still does hashing, not
encryption. The difference is subtle, but one should be aware that
hashing serves a different purpose than encryption, so not all hashing
algorthms are well suited for one way encryption.

He is not using the hash to encrypt. He is using the hash to help
derive a secure keu from the user's password. He is using 3DES to do
the actual encryption.

rossum
 
public string JJEncryption(string password)
Random is not cryptographically secure. For a cryptographically
secure PRNG use System.Security.Cryptography.RandomNumberGenerator
Alternatively, write your own - google 'Yarrow' or 'Fortuna' for
examples.
Have looked into the secure random Int32 and have come up with this.

public int CreateSecureRandomInt()
{
RNGCryptoServiceProvider random = new
RNGCryptoServiceProvider();
byte[] randBytes = new byte[4];
random.GetNonZeroBytes(randBytes);
int i = (BitConverter.ToInt32(randBytes,0));
if (i < 0)
i += (i - (i * 2)) - i;
string s = i.ToString();
s = s.Substring(1, 1);
return (Int32.Parse(s));
}
Is this what you ment ?
Or have i gone of on a tanjant ?

Still reading about the rest before i try and implerment as i have to have
an understanding
of the code to produce the required write up.
 
Random is not cryptographically secure. For a cryptographically
secure PRNG use System.Security.Cryptography.RandomNumberGenerator
Alternatively, write your own - google 'Yarrow' or 'Fortuna' for
examples.
Have looked into the secure random Int32 and have come up with this.

public int CreateSecureRandomInt()
{
RNGCryptoServiceProvider random = new
RNGCryptoServiceProvider();
byte[] randBytes = new byte[4];
random.GetNonZeroBytes(randBytes);
By only taking non-zero bytes you are reducing the amount of
randomness (= entropy). Better not to do this.
int i = (BitConverter.ToInt32(randBytes,0));
At this point overwrite randBytes[] since you do not need it any more.
if (i < 0)
i += (i - (i * 2)) - i;
Better to pick a new random number until you get a positive one. The
point is to interfere as little as possible with what the RNG gives
you. The more you interfere the less random it is.

do {
random.GetNonZeroBytes(randBytes);
i = (BitConverter.ToInt32(randBytes,0));
while (i < 0);
string s = i.ToString();
s = s.Substring(1, 1);
return (Int32.Parse(s));
Why go to strings, which leave clear copies of your random number
lying around on the heap? If you want the second most significant
digit of your random number then you can get at it by manipulating the
integer directly: divide by 10 until the number is < 100, then take
mod 10.

rossum
 
Thank you very much for your help dont want to annoy you to much.

I have changed the requested... and hopefully this is what you ment.

private int CreateSecureRandomInt()
{
RNGCryptoServiceProvider random = new
RNGCryptoServiceProvider();
byte[] randBytes = new byte[4];
random.GetBytes(randBytes);
int i = (BitConverter.ToInt32(randBytes,0));
randBytes = null;

if (i < 0)
CreateSecureRandomInt();

while (i > 10)
{
i = i / 10;
}

return i;
}

I will work on the rest of the "fixes" over the next few days and will post
back.

I tried replacing this ...
tdes.Mode = CipherMode.ECB;

with...
tdes.Mode = CipherMode.CBC;

But it seems to output characters which can not be converted to base64,
which would mean a big change.
I need to do some more reading.

Once again thanks

Regards JJ (UWA)
 
j1mb0jay said:
Ok just for you...... since im not planning on using it any where other
than coursework, heres the code to decrypt, try them !!

I assure you they work.


public string JJDycryption(string ePassword)
{

string nonB64password = MD5Decrypt(ePassword,true);

char[] splitter = { '-' };

string[] s = nonB64password.Split(splitter);

int milli = Convert.ToInt32(ConvertFromBase64(s[0]));

int ramdom = Convert.ToInt32(ConvertFromBase64(s[1]));

milli = milli + ramdom;

string password = string.Empty;

for (int index = 2; index < s.Length; index++)

{

int i = Convert.ToInt32(s[index]);

i = i - milli;

char c = Convert.ToChar(i);

password = password + c.ToString();

}

return password;

}

private string MD5Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
//get the byte code of the string

byte[] toEncryptArray = Convert.FromBase64String(cipherString);

System.Configuration.AppSettingsReader settingsReader = new
AppSettingsReader();
//Get your key from config file to open the lock!
string key = ApplicationSettings.MeetySettings.Key;

if (useHashing)
{
//if hashing was used get the hash code with regards to
your key
MD5CryptoServiceProvider hashmd5 = new
MD5CryptoServiceProvider();
keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//release any resource held by the MD5CryptoServiceProvider

hashmd5.Clear();
}
else
{
//if hashing was not implemented get the byte code of the
key
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)

tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}

private string ConvertFromBase64(string text)
{
string ret = string.Empty;
byte[] enc = System.Convert.FromBase64String(text);
for (int i = 0; i < enc.Length; i++)
{
ret += System.Convert.ToChar(enc).ToString();
}
return ret;
}

Regards JJ (UWA)


Oh, I see now what you are doing. The name of the MD5Encrypt method is
misleading in a slightly different way than I said. It doesn't try to do
MD5 encryption at all, it does MD5 hashing of the key and TripleDES
encryption of the data.
 
What an enjoyable change from what I dare say most of us typically see.
Somebody has a serious question, posts examples rather than ask for the code
to be written and they listen to advice and revise things :-) This is what
makes it worth it...

Now... I think you have a potential recursion issue here. Not likely to
continue on too deeply perhaps but because you repeatedly call
CreateSecureRandomInt() you can create a lot of objects and the stack has to
unwind when it finally gets a positive value. You might want to tidy that
up as you have time.

Tom
 
Back
Top