When using c# rijndael to decrypt a string that was previously encrypted and saved in sql server ce, I get nothing back from decryption. I can tell from debugging and checking the database that the decrypted string appears to be saved as expected with different sets of nonsense for different input strings so I assume that the problem is in the decryption code. I also confirmed that cipherText input parameter got the correct number of bytes after being retrieved from the db and re-made into a byte array. I used the example found at: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael%28v=vs.110%29.aspx to do this, with some modifications.
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plainText = null;
// Create an Rijndael object
// with the specified key and IV.
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Padding = PaddingMode.PKCS7;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
var plainBytes = new byte[cipherText.Length];
int plainByteCount;
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
plainByteCount = csDecrypt.Read(plainBytes, 0, plainBytes.Length);
using (StreamReader srDecrypt = new StreamReader(csDecrypt, System.Text.Encoding.Unicode))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plainText = srDecrypt.ReadToEnd();
}
}
}
plainText = Encoding.Unicode.GetString(plainBytes, 0, plainBytes.Length);
}
return plainText;
}
At
plainText = srDecrypt.ReadToEnd();
plainText gets the value of "" where I would expect it to be the decrypted word.
Finally, at
plainText = Encoding.Unicode.GetString(plainBytes, 0, plainBytes.Length);
plainText becomes: "\0\0\0\0\0\0\0\0"
I have tried various padding options, both at the encryption and decryption stages, and can see that doing so has an effect but it doesn't solve the problem. Without setting padding 0 bytes get encrypted in the first place, where it should be 16 bytes. I also tried different ways of calling flush and flushfinalblock. I am storing the key/iv in plain text files (I am aware that may not be best practice for security, my goal for now is only to learn more about this topic).
Please help me find what I am doing wrong here.