Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using Encryption

Status
Not open for further replies.

Mannga

Programmer
Jun 21, 2002
85
GB
I am trying to get some very basic encryption going and I think it is half working.

I have the following

public class Encryption
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
private byte[] Output = null;
public byte[] Encrypt( byte[] Data )
{
Output = rsa.Encrypt(Data,false);
return(Output);
}
public byte[] Decrypt( byte[] Data )
{
Output = rsa.Decrypt(Data,false);
return(Output);
}
}

I then call this from my other form

I then pass a byte Array to these functions and I receive an Encrypted byte Array in return. I then save this to a file and everything seems to be working, but when I try and decrypt it I get a error saying "Bad Data"?

Can someone please let me know what I am doing wrong here?
It seems easy enough but just doesn't want to work.
My code on my form looks like this

**To Encrypt Values**
Encryption enc = new Encryption();
Encoding encode = Encoding.GetEncoding(0);
string Server = dtServer.Text;
byte[] bServer = encode.GetBytes(Server);
bServer = enc.Encrypt(bServer);

FileStream fs = new FileStream(nFile, FileMode.Truncate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("$SERVER$=$" + encode.GetString(bServer) + "$");
sw.Close();

**To Decrypt Values**
Encryption enc = new Encryption();
Encoding encode = Encoding.GetEncoding(0);
FileStream fs = new FileStream(nFile, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string rLine;
string[] aLine;
while( sr.Read() > 0 )
{
rLine = sr.ReadLine();
aLine = rLine.Split('$');
if( aLine.GetUpperBound(0) > 0 )
{
if( aLine[0] == "SERVER" )
{
byte[] stest = encode.GetBytes(aLine[2]);
stest = enc.Decrypt(stest);//ERROR HERE
dtServer.Text = encode.GetString(stest);
}
}
}
sr.Close();
fs.Close();

Thanks,
Gavin
 
Every time you create a new RSACryptoServiceProvider, it generates a new key. That means that every time you create a new Encryption object, you will have a different key.
You create once an Encryption object when you encrypt, and once when you decrypt, and the keys will not match.
You have thus to assure that the key used for encrypting a string is the same when decrypting.
The good news is that you can use the CryptoStream class if you want to write in a file, and this would be easier...
 
Okay I have been trying to figure this out but am not getting anywhere here.

What I would like to do is pass a function a string and it will return an encrypted string. Then next time the application is started I would like to pass an excrypted string to a seperate function and to return a decrypted string.

How can this be so difficult?

Thanks,
Gavin
 
Do you understand the basics of cryptography? Whenever you crypt or decrypt something you have to use a key. If you encrypt something and then you try to decrypt it, you have to use the key used when you encrypted the message.
Ok, let's pass to implementation details. Your code looks like this:

**To Encrypt Values**
Encryption enc = new Encryption();

What happens now is that the following line from the Encryption class is executed:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

Ok, that initializes rsa with a new value, by executing the constructor with no parameters. Citing from MSDN:

The above constructor "Initializes a new instance of the RSACryptoServiceProvider class using the default key.
...
Remarks
If no default key is found, a new key is created."

Well, if you had a default key, you would have no problem. You have this problem, so you didn't defined any key as default. So a new key is created for encryption.

What happens when you try to decrypt the string? Well, you do exactly the same thing. That means that another key is created for decryption, and, unless you are very very lucky, the encryption key will never ever be the same with the decryption key!

Ok, so what can you do?
Some possible answers are:
- Define a default key (I'm not sure how this is done, but we can look together, if you want to)
- Don't use the constructor with no arguments for RSACryptoServiceProvider, but the one with the argument specifying the key. Assure that you are using the same key by keeping it somewhere(in a variable in code, in an external file, in a resource dll etc.)

As a final remark, I think that you might have to generate the key to use because this cryptography mechanism is integrated with Windows 2000 security. There is a utility in VS that helps you do this. I would use CryptoStream if I were you...
Ok, if I convinced you, I can help you go further, if you understood and if you choose one method of solving things.
Regards,
Alex
 
Okay... I got most of your message and I understand what you are saying.

There are a couple of options here but what I am looking for is the simplest :)...

I have the following using CryptoStream

public string Encrypt(System.Windows.Forms.TextBox textBox)
{
UnicodeEncoding UE = new UnicodeEncoding();
string KeyCode = "LONDONTB";
byte[] key = UE.GetBytes(KeyCode);
byte[] decString = UE.GetBytes(textBox.Text);
MemoryStream ms=new MemoryStream(decString);
MemoryStream ms2=new MemoryStream();
CryptoStream cs = new CryptoStream(ms2, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write);
int data;
while ((data=ms.ReadByte())!=-1)
cs.WriteByte((byte) data);
string Encrypted = "";
ms2.Close();
ms.Close();
return(Encrypted);
}

Which runs without any errors (YAY).. but which obviously does not return anything but a blank.
Now I would presume my encrypted string is sitting inside 'ms2' or 'cs'?

How do I get this our of here?

Thanks,
Gavin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top