hey there, so in a msSQL database that i'm saving and retrieving from using stored procedures. i'm trying to encrypt some data in the c# windows form before being placed, and then of course decrypting it when i pull it back. all the encryption is being handled on the c# side. i'm using the sample code for encryption and decryption verbatim from microsoft's tripleDESCryptoService Class (the memory version, 2nd example). The values get encrypted and sent to the database, but when retrieving it i get a "bad data" error. a sample of the encryption call is...
TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
byte[] tempByte = new byte[100];
tempByte = encrypt(txt_Last_Name.Text, tDESalg.Key, tDESalg.IV);
txt_Last_Name.Text = System.Text.ASCIIEncoding.ASCII.GetString(tempByte);
the txt_Last_Name is then sent to the database, and i can see that there is something in the database. in the database, last name is of type varchar(20)
sample of the decryption call is...
TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
string lastName = dr.GetString(dr.GetOrdinal("Last Name"));
if (isEncrypted)
{
byte[] toDecrypt = new ASCIIEncoding().GetBytes(lastName);
lastName = decrypt(toDecrypt, tDESalg.Key, tDESalg.IV);
}
txt_Last_Name.Text = lastName;
it bombs in the decryption function at: "csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);" and i don't understand why. i'm not sure if it's not getting stored in the database correctly, or my conversions aren't right.
if it means anything, the "Data" coming into the decrypt function is of size 16 and contains non-zero values, but the "byte[] fromEncrypt" is an array of size 16 containing all zeros.
thanks for any help!
EDIT: Okay, we've got to the bottom of it... although the ASCII issue would have bitten too.
Every time you create a new
TripleDESCryptoServiceProvider
and ask it for a key/IV, it will generate a new one. You need to store that securely somewhere, as it's required to decrypt the data. Otherwise you don't have any "secret" so it's not really encryption...This is a terrible idea:
You've got arbitrary binary data in
tempByte
. Don't assume it's valid ASCII text. That's almost certainly where you're losing data.Use
Convert.ToBase64String
andConvert.FromBase64String
to safely encode opaque binary data as text.Additionally, this is a bad idea:
What's the point of creating a byte array if you're then going to ignore it? Use
instead. Oh, and try to follow .NET naming conventions :)
Having said all of this, if your encryption is always returning a byte array of 16 zeroes, that's a pretty sure sign that your
encrypt
method is broken. We can't really help there until you post the code for that method.Finally, if your column is of type
varchar(20)
you should be aware that that may very well not hold all the data you need it to... particularly if you're going to include a salt. Base64 will increase the size of the data somewhat, and encryption may do so too. As mentioned in another answer, storing this as binary in the database would be more sensible in many ways.(Note: even if you did want to use that code, I'd write it as
txt_Last_Name.Text = Encoding.ASCII.GetString(tempByte);
. Using directives are your friend, andASCII
is a property ofEncoding
, notASCIIEncoding
.)