I'm working on a website, where users are able to upload files. I want to encrypt these files, in case there is some kind of security breach where access is granted to them.
When the user wants to download their files, I decrypt directly to the HTTP(S) output stream.
The files are placed on disc, and a record for each is inserted in the website database with some additional data (file name, size, file path, IV and such).
I only have a basic understanding of how to use encryption and therefore have some questions.
I'm using Rfc2898DeriveBytes
to generate the bytes for the encryption key. Is it okay to use this class? As far as I know it uses SHA1, which might no longer be secure?
Right now I'm using the same password and salt for each encryption, but a random IV each time. Should I also be randomizing the salt and keep it in the database along with the IV? Will this give additional security?
Should I be using a message authentication code (MAC)? The encrypted files themselves are only stored and never transferred, so I don't know if it's necessary.
I don't really know how to best store the encryption password. I don't want to include it in my website DLL, so I'll probably have it in a file on the server somewhere that isn't in my website folder. How else could I be doing this?
This is my code for encryption. Any obvious security flaws?
const int bufferSize = 1024 * 128;
Guid guid = Guid.NewGuid();
string encryptedFilePath = Path.Combine(FILE_PATH, guid.ToString());
byte[] rgbIV;
using (Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes("PASSWORD HERE", Encoding.ASCII.GetBytes("SALT HERE")))
{
byte[] rgbKey = deriveBytes.GetBytes(256 / 8);
using (FileStream decryptedFileStream = File.OpenRead(decryptedFilePath))
using (FileStream encryptedFileStream = File.OpenWrite(encryptedFilePath))
using (RijndaelManaged algorithm = new RijndaelManaged() { KeySize = 256, BlockSize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.ISO10126 })
{
algorithm.GenerateIV();
rgbIV = algorithm.IV;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(rgbKey, rgbIV))
using (CryptoStream cryptoStream = new CryptoStream(encryptedFileStream, encryptor, CryptoStreamMode.Write))
{
int read;
byte[] buffer = new byte[bufferSize];
while ((read = decryptedFileStream.Read(buffer, 0, bufferSize)) > 0)
cryptoStream.Write(buffer, 0, read);
cryptoStream.FlushFinalBlock();
}
}
}