title: Key, salt and IV when using Rijndael encryption
body: <p>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.</p>
  
  <p>When the user wants to download their files, I decrypt directly to the HTTP(S) output stream.</p>
  
  <p>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).</p>
  
  <p>I only have a basic understanding of how to use encryption and therefore have some questions.</p>
  
  <p>I'm using <code>Rfc2898DeriveBytes</code> 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?</p>
  
  <p>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?</p>
  
  <p>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.</p>
  
  <p>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?</p>
  
  <p>This is my code for encryption. Any obvious security flaws?</p>
  
  <pre><code>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)) &gt; 0)
                  cryptoStream.Write(buffer, 0, read);
              cryptoStream.FlushFinalBlock();
          }
      }
  }
  </code></pre>