Tuesday, December 23, 2008

Strings to bytes and encoding.

I recently found a need to know what the byte array of a sting of text was for multiple encodings. So I wrote a small utility that will show what the byte array of typed text is. Maybe somebody else will find it useful too I'm releasing it as free software:

Get it here ---> EncodingViewerSetup.exe

It supports UTF32, Unicode(UTF16), UTF8, UTF7, and ASCII.

cheers,
-bb

Monday, December 22, 2008

RSA in C# .NET

After a day of googlin' and testing I finally tracked down my issue:

The goal:

0)RSAObject:
  • Encrypt : takes a plain text string and returns an encrypted string.
  • Decrypt: takes an encrypted string and returns a plain text string.
1)Server:
  • Generate a RSA public and private key.
  • Pass the public key in plain text to the client
2)Client:
  • Pass a plain string to RSAObject
  • Pass encrypted string from RSAObject to Server.
3)Server:
  • Pass encrypted string to RSAObject
  • Use decrypted string from RSAObject.

PROBLEMS:

My origional code for encrypting and decrypting data:

public string Encrypt(string plainText)
{
try
{
byte[] plainData = Encoding.UTF32.GetBytes(plainText);
byte[] encryptedData = crypto.Encrypt(plainData, true);
return Encoding.UTF32.GetString(encryptedData);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return "";
}
}

public string Decrypt(string encryptedText)
{
try
{
byte[] encryptedData =
Encoding.UTF32.GetString(encryptedText);
byte[] plainData = crypto.Decrypt(encryptedData, true);
return
Encoding.UTF32.GetString(plainData);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return "";
}
}

All I would get during decryption from crypto, a RSACryptoServiceProvider object, was one of two exceptions:
  1. Bad Length
  2. Error occurred while decoding OAEP padding.
After reading up more on RSA I discovered that a UTF32(32bit) can't properly handle the data returned by crypto.Encrypt, therefore some of my bytes were being changed in the conversion process to UTF32, and therefor could not be decrypted. use Convert.ToBase64String(string)



SOLUTION:
Encrypt method needs to convert to a 64bit string.
Decrypt method needs to convert from a 64bit string.

fixed and working source code:

public string Encrypt(string plainText)
{
try
{
byte[] plainData = Encoding.UTF32.GetBytes(plainText);
byte[] encryptedData = crypto.Encrypt(plainData, true);
return Convert.ToBase64String(encryptedData);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return "";
}
}

public string Decrypt(string encryptedText)
{
try
{
byte[] encryptedData = Convert.FromBase64String(encryptedText);
byte[] plainData = crypto.Decrypt(encryptedData, true);
return Encoding.UTF32.GetString(plainData);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return "";
}
}


cheers,
-bb