/// <summary> /// Encrypts the given file, using the private hashed hashedKey /// </summary> /// <param name="originalFile"></param> /// <param name="key"></param> /// <param name="deleteOriginalSafely"></param> public static FileInfo Encrypt(FileInfo originalFile, string key, bool deleteOriginalSafely = false) { if (originalFile == null) { throw new ArgumentNullException(nameof(originalFile)); } if (!originalFile.Exists) { throw new ArgumentException($"{nameof(originalFile)} points to a non-existant file"); } if (Directory.Exists(originalFile.FullName)) { throw new ArgumentException($"{nameof(originalFile)} points to a folder, not a file"); } // ready encryption hashedKey and info var info = new EncryptionInfo { Version = Application.ProductVersion, HashAlgorithm = typeof(SHA256CryptoServiceProvider), EncryptionAlgorithm = typeof(AesCryptoServiceProvider), KeySize = 256, BlockSize = 128, SaltSize = 128 }; byte[] hashedKey; EncryptKey(key, info, out hashedKey); // hash original file var hash = Hash(originalFile, info.HashAlgorithm); var newFile = Core.GetNonCollidingFile(originalFile.FullName + Settings.Default.Extension); // encrypt original file with info header in the start using (var tempFiles = new TempFileGenerator()) using (var crypter = new AesCryptoServiceProvider()) { // load hashedKey and IV into cryptography service crypter.Key = hashedKey; crypter.GenerateIV(); //Debug.Assert(crypter.ValidKeySize(256)); // create temporary files var zippedFile = tempFiles.CreateFile(); // zip original file into temporary zipped file using (var zippedFs = zippedFile.OpenWrite()) using (var zipper = new GZipStream(zippedFs, CompressionMode.Compress)) using (var originalFs = originalFile.OpenRead()) originalFs.CopyTo(zipper); //progressBar.BeginInvoke(new Action(() => { progressBar.Increment(5); })); // add Json header to final file with a text stream using (var newFs = newFile.CreateText()) { info.OriginalHash = hash; info.Iv = crypter.IV; newFs.Write(JsonConvert.SerializeObject(info)); } // encrypt zipped file into final file, as an append using (var zippedFs = zippedFile.OpenRead()) using ( var cs = new CryptoStream(zippedFs, crypter.CreateEncryptor(), CryptoStreamMode.Read)) using (var newFs = newFile.Open(FileMode.Open, FileAccess.ReadWrite)) { newFs.Seek(0, SeekOrigin.End); cs.CopyTo(newFs); } // delete hashed key Core.ShallowEraseList(hashedKey); // safely delete the zipped file, as it shouldn't stay in the OS like that SafeOverwriteFile(zippedFile); zippedFile.Delete(); } // safe deleting of the original file if (!deleteOriginalSafely) { return(newFile); } SafeOverwriteFile(originalFile); originalFile.Delete(); return(newFile); }