} //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