Пример #1
0
        /// <summary>
        /// Decrypts the selected file using the given password
        /// </summary>
        /// <param name="inputFile">Encrypted File</param>
        /// <param name="password">Password to decrypt the file</param>
        /// <param name="percentComplete">Percent of completion</param>
        /// <returns>If the decryption was successful</returns>
        internal bool Decrypt(string inputFile, string password, ref decimal percentComplete)
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

            FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);

            fsCrypt = DecryptModeHandler(fsCrypt, out byte[] hash, out byte[] salt, out byte[] faesCBCMode, out byte[] faesMetaData, out var cipher);

            const int          keySize   = 256;
            const int          blockSize = 128;
            Rfc2898DeriveBytes key       = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
            RijndaelManaged    AES       = new RijndaelManaged
            {
                KeySize   = keySize,
                BlockSize = blockSize,
                Key       = key.GetBytes(keySize / 8),
                IV        = key.GetBytes(blockSize / 8),
                Padding   = PaddingMode.PKCS7,
                Mode      = cipher
            };

            try
            {
                CryptoStream cs         = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);
                string       outputName = Path.ChangeExtension(inputFile, FileAES_Utilities.ExtentionUFAES);

                try
                {
                    FileStream fsOut = new FileStream(outputName, FileMode.Create);
                    File.SetAttributes(outputName, FileAttributes.Hidden);

                    byte[] buffer           = new byte[FileAES_Utilities.GetCryptoStreamBuffer()];
                    long   expectedComplete = fsCrypt.Length + hash.Length + salt.Length + faesCBCMode.Length + faesMetaData.Length + AES.KeySize + AES.BlockSize;

                    try
                    {
                        int read;
                        Logging.Log("Beginning writing decrypted data...", Severity.DEBUG);
                        while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            try
                            {
                                percentComplete = Math.Ceiling((decimal)((Convert.ToDouble(fsOut.Length) / Convert.ToDouble(expectedComplete)) * 100));
                                if (percentComplete > 100)
                                {
                                    percentComplete = 100;
                                }
                            }
                            catch
                            {
                                Logging.Log("Percentage completion calculation failed!", Severity.WARN);
                            }

                            fsOut.Write(buffer, 0, read);
                        }
                        Logging.Log("Finished writing decrypted data.", Severity.DEBUG);
                    }
                    catch
                    {
                        fsOut.Close();
                    }

                    cs.Close();
                    fsOut.Close();
                    fsCrypt.Close();

                    if (Checksums.ConvertHashToString(hash) != Checksums.ConvertHashToString(Checksums.GetSHA1(outputName)))
                    {
                        Logging.Log("Invalid Checksum detected! Assuming password is incorrect.", Severity.DEBUG);
                        FileAES_IntUtilities.SafeDeleteFile(outputName);
                        return(false);
                    }
                    Logging.Log("Valid Checksum detected!", Severity.DEBUG);
                    return(true);
                }
                catch
                {
                    cs.Close();
                    fsCrypt.Close();

                    return(false);
                }
            }
            catch (CryptographicException)
            {
                fsCrypt.Close();
                return(false);
            }
        }