I'm having some trouble with the code below. I have a file in a temporary location which is in need of encryption, this function encrypts that data which is then stored at the "pathToSave" location.
On inspection is does not seem to be handling the whole file properly - There are bits missing from my output and I suspect it has something to do with the while loop not running through the whole stream.
As an aside, if I try and call CryptStrm.Close() after the while loop I receive an exception. This means that if I attempt to decrypt the file, I get a file already in use error!
Tried all the usual and Ive looked on here at similar issues, any help would be great.
Thanks
public void EncryptFile(String tempPath, String pathToSave)
{
try
{
FileStream InputFile = new FileStream(tempPath, FileMode.Open, FileAccess.Read);
FileStream OutputFile = new FileStream(pathToSave, FileMode.Create, FileAccess.Write);
RijndaelManaged RijCrypto = new RijndaelManaged();
//Key
byte[] Key = new byte[32] { ... };
//Initialisation Vector
byte[] IV = new byte[32] { ... };
RijCrypto.Padding = PaddingMode.None;
RijCrypto.KeySize = 256;
RijCrypto.BlockSize = 256;
RijCrypto.Key = Key;
RijCrypto.IV = IV;
ICryptoTransform Encryptor = RijCrypto.CreateEncryptor(Key, IV);
CryptoStream CryptStrm = new CryptoStream(OutputFile, Encryptor, CryptoStreamMode.Write);
int data;
while (-1 != (data = InputFile.ReadByte()))
{
CryptStrm.WriteByte((byte)data);
}
}
catch (Exception EncEx)
{
throw new Exception("Encoding Error: " + EncEx.Message);
}
}
EDIT:
I've made the assumption that my problem is with Encryption. My Decrypt might be the culprit
public String DecryptFile(String encryptedFilePath)
{
FileStream InputFile = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read);
RijndaelManaged RijCrypto = new RijndaelManaged();
//Key
byte[] Key = new byte[32] { ... };
//Initialisation Vector
byte[] IV = new byte[32] { ... };
RijCrypto.Padding = PaddingMode.None;
RijCrypto.KeySize = 256;
RijCrypto.BlockSize = 256;
RijCrypto.Key = Key;
RijCrypto.IV = IV;
ICryptoTransform Decryptor = RijCrypto.CreateDecryptor(Key, IV);
CryptoStream CryptStrm = new CryptoStream(InputFile, Decryptor, CryptoStreamMode.Read);
String OutputFilePath = Path.GetTempPath() + "myfile.name";
StreamWriter OutputFile = new StreamWriter(OutputFilePath);
OutputFile.Write(new StreamReader(CryptStrm).ReadToEnd());
CryptStrm.Close();
OutputFile.Close();
return OutputFilePath;
}
Well, there are several things going wrong here.
1. Your setting the size of the IV too large. If you have a key size of 256, the IV for Rijndael is 16 bytes. If you try to set the key with more bytes than that you will get an exception. IV size should be set to Block size / 8 see MSDN so the IV size you have is correct.
I am posting some sample code using memory streams to show the encrypting and decrypting.
var tempData = "This is the text to encrypt. It's not much, but it's all there is.";
using (var rijCrypto = new RijndaelManaged())
{
byte[] encryptedData;
rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rijCrypto.KeySize = 256;
using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
using (var output = new MemoryStream())
{
var encryptor = rijCrypto.CreateEncryptor();
using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
{
var buffer = new byte[1024];
var read = input.Read(buffer, 0, buffer.Length);
while (read > 0)
{
cryptStream.Write(buffer, 0, read);
read = input.Read(buffer, 0, buffer.Length);
}
cryptStream.FlushFinalBlock();
encryptedData = output.ToArray();
}
}
using (var input = new MemoryStream(encryptedData))
using (var output = new MemoryStream())
{
var decryptor = rijCrypto.CreateDecryptor();
using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
{
var buffer = new byte[1024];
var read = cryptStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
output.Write(buffer, 0, read);
read = cryptStream.Read(buffer, 0, buffer.Length);
}
cryptStream.Flush();
var result = Encoding.Unicode.GetString(output.ToArray());
}
}
}