private void EncryptFiles(PasswordAndFiles passwordAndFiles) { foreach (string file in passwordAndFiles.Files) { try { if (FileStarted != null) FileStarted(file); FileInfo fileInfo = new FileInfo(file); // Perform a seperate encryption function to encrypt the header information EncryptionHeader header = new EncryptionHeader(Path.GetFileName(file), fileInfo.LastWriteTime); // Create an IV byte[] iv = new byte[HeaderInfo.IvSize]; RNGCryptoServiceProvider.Create().GetBytes(iv); byte[] headerBytes = header.Create(iv, passwordAndFiles.Password); string newInputFileName = file; string encryptedFileName = file; encryptedFileName = GetVerifiedUniqueFileName(string.Format("{0}{1}{2}[0]{3}", Path.GetDirectoryName(file), Path.DirectorySeparatorChar, dataSafeFileNamePrefix, dataSafeFileExtension)); using (FileStream inputFile = File.Open(newInputFileName, FileMode.Open, FileAccess.Read, FileShare.None)) { using (FileStream outputFile = File.Open(encryptedFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { StreamEncryption(headerBytes, inputFile, outputFile, GetKeyFromPassword(passwordAndFiles.Password, header.PasswordSalt), header.InitializationVector); } } // Try to wipe the file SuperDeleteFile(newInputFileName); } catch (Exception e) { string logFile = GetVerifiedUniqueFileName(Path.GetDirectoryName(file) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + "_DataSafeLog.txt"); StringBuilder sb = new StringBuilder(); sb.AppendFormat("There was an error encrypting the file: {0}\r\n\r\n", file); sb.Append(e.ToString()); File.WriteAllText(logFile, sb.ToString()); } finally { counter++; if (FileFinished != null) FileFinished(file, totalFiles, counter); } } }
private void DecryptFiles(PasswordAndFiles passwordAndFiles) { foreach (string file in passwordAndFiles.Files) { try { if (FileStarted != null) FileStarted(file); bool decrypted = false; bool sourceSameAsDest = false; string outputFileName; using (FileStream inputFile = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { // Get the header information EncryptionHeader header = new EncryptionHeader(inputFile, passwordAndFiles.Password); outputFileName = header.OriginalFileName; // Are the destination file and source file the same? If so, flag it. sourceSameAsDest = Path.GetFileName(file) == outputFileName; // This is here in case they have another file in this directory that has the same name as the soon-to-be-decrypted file. outputFileName = GetVerifiedUniqueFileName(string.Format("{0}{1}{2}", Path.GetDirectoryName(file), Path.DirectorySeparatorChar, outputFileName)); using (FileStream outputFile = File.Open(outputFileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) { StreamEncryption(inputFile, outputFile, GetKeyFromPassword(passwordAndFiles.Password, header.PasswordSalt), header.InitializationVector); // Double-checking to make sure we got through the decryption so we don't delete anything otherwise... // This shouldn't be necessary, but it's here anyway :) decrypted = true; } } if (decrypted) { // Do a simple delete on the encrypted file... no point in wiping it. File.Delete(file); if (sourceSameAsDest && outputFileName != null) File.Move(outputFileName, file); } } catch (Exception e) { string logFile = GetVerifiedUniqueFileName(Path.GetDirectoryName(file) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + "_DataSafeLog.txt"); StringBuilder sb = new StringBuilder(); sb.AppendFormat("There was an error decrypting the file: {0}\r\n", file); sb.Append("The most likely cause of this error is an invalid password. \r\n"); sb.Append("Another likely cause is that the file you were trying to decrypt was not actually encrypted. \r\n"); sb.Append("This file might also be incorrectly encrypted - using a different encryption method or something. \r\n"); sb.Append(e.ToString()); File.WriteAllText(logFile, sb.ToString()); } finally { counter++; if (FileFinished != null) FileFinished(file, totalFiles, counter); } } }