} //End method //Implements IEncryptionMachine.Decrypt2 //Main user interface for the FortMachine library. //This method can be used to decrypt big files as it uses stream based operation for reading and //writing the data. //Returns true on success, false on failure. public bool Decrypt2(string passphrase, string inputpath, string outputpath) { FileStream StreamIn = null; FileStream StreamOut = null; CryptoStream decrypto = null; FileStream NewPlainStream = null; //Make sure our outputpath has correct encoding //byte[] filenamebytes = Encoding.Default.GetBytes(outputpath); //outputpath = Encoding.Default.GetString(filenamebytes); try { byte[] key; byte[] IV; byte[] salt; byte[] magic_header; int BufferSize = 4096; byte[] buffer = new byte[BufferSize]; int BytesRead; byte[] IntegrityHash; IV = new byte[FortMachineConstants.IV_SIZE]; salt = new byte[FortMachineConstants.SALT_SIZE]; magic_header = new byte[FortMachineConstants.MAGIC_HEADER_SIZE]; IntegrityHash = new byte[FortMachineConstants.DATA_INTEGRITY_HASH_SIZE]; StreamIn = new FileStream(inputpath, FileMode.Open, FileAccess.ReadWrite); StreamOut = new FileStream(outputpath, FileMode.OpenOrCreate, FileAccess.Write); //Ignore the magic header and move file pointer to the next bytes StreamIn.Read(magic_header, 0, FortMachineConstants.MAGIC_HEADER_SIZE); //Read the IV into the buffer StreamIn.Read(IV, 0, FortMachineConstants.IV_SIZE); //Read passphrase salt into a buffer StreamIn.Read(salt, 0, FortMachineConstants.SALT_SIZE); //Read data integrity hash StreamIn.Read(IntegrityHash, 0, FortMachineConstants.DATA_INTEGRITY_HASH_SIZE); key = this.ProcessKeyWithSalt(passphrase, salt); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.Key = key; aes.IV = IV; aes.Mode = CipherMode.CBC; decrypto = new CryptoStream(StreamOut, aes.CreateDecryptor(), CryptoStreamMode.Write); do { BytesRead = StreamIn.Read(buffer, 0, BufferSize); decrypto.Write(buffer, 0, BytesRead); } while (BytesRead != 0); decrypto.Close(); StreamIn.Close(); //Create new temporary stream from the decrypted file to verify data integrity NewPlainStream = new FileStream(outputpath, FileMode.Open, FileAccess.Read); //Verify data integrity if (!DataIntegrity.VerifyHash(NewPlainStream, key, IntegrityHash)) { this._IsDataTampered = true; } else { this._IsDataTampered = false; } NewPlainStream.Close(); File.Delete(inputpath); } catch (Exception ex) { //Clean up streams, if they where created if (decrypto != null) { decrypto.Close(); } if (StreamOut != null) { StreamOut.Close(); } if (StreamIn != null) { StreamIn.Close(); } if (NewPlainStream != null) { NewPlainStream.Close(); } //As decryption failed, check if the output file was created and delete it //because it would be incomplete. if (File.Exists(outputpath)) { File.Delete(outputpath); } this._LastErrorMessage = "Decryption failed: " + ex.Message; return(false); } return(true); } //End method
} //End method //Implements IEncryptionMachine.Encrypt2 //Main user interface for the FortMachine library. //This method can be used to encrypt big files as stream based operations are used and //data is not read into memory at once. public bool Encrypt2(string passphrase, string inputpath, string outputpath, bool KeepPlainFile = false) { FileStream StreamIn = null; FileStream StreamOut = null; CryptoStream crypto = null; try { byte[] IV; FortKey key; byte[] KeyBytes; int BufferSize = 4096; byte[] buffer = new byte[BufferSize]; int BytesRead; byte[] IntegrityHash; key = this.CreateKey(passphrase); KeyBytes = key.GetNew(); IV = this.GetRandom16IV(); StreamIn = new FileStream(inputpath, FileMode.Open, FileAccess.Read); StreamOut = new FileStream(outputpath, FileMode.OpenOrCreate, FileAccess.Write); IntegrityHash = DataIntegrity.GetHMACHash(StreamIn, KeyBytes); StreamIn.Seek(0, SeekOrigin.Begin); //First write our magic header to mark that the file is encrypted with Fort StreamOut.Write(FortMachineConstants.MAGIC_HEADER, 0, FortMachineConstants.MAGIC_HEADER_SIZE); //Then, write IV into the file StreamOut.Write(IV, 0, FortMachineConstants.IV_SIZE); //Then, write the salt into the file StreamOut.Write(key.Salt, 0, FortMachineConstants.SALT_SIZE); //Then, write the integrity has into the file StreamOut.Write(IntegrityHash, 0, FortMachineConstants.DATA_INTEGRITY_HASH_SIZE); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.Key = KeyBytes; aes.IV = IV; aes.Mode = CipherMode.CBC; crypto = new CryptoStream(StreamOut, aes.CreateEncryptor(), CryptoStreamMode.Write); do { BytesRead = StreamIn.Read(buffer, 0, BufferSize); crypto.Write(buffer, 0, BytesRead); } while (BytesRead != 0); crypto.Close(); StreamIn.Close(); if (!KeepPlainFile) { File.Delete(inputpath); } } catch (Exception ex) { if (crypto != null) { crypto.Close(); } if (StreamIn != null) { StreamIn.Close(); } if (File.Exists(outputpath)) { File.Delete(outputpath); } this._LastErrorMessage = "Encryption failed: " + ex.Message; return(false); } return(true); } //End method