如何使用 AES 加密文本文件以外的文件? PDF、Word等

How can I use AES to encrypt files other than text files? PDF, Word, etc

我正在尝试 encrypt/decrypt C# ASP NET 5.0 中的文件,当然我可以让它为 .txt 文件和常规字符串工作。但是如果我尝试加密 PDF 文件然后解密它,它已损坏并且我无法打开它。我现在只是在使用 EBC,我知道它不安全,但我只是想在添加其他选项之前对其进行测试。

    public static void encrypt(string fileLocation, string encryptedFileLocation, string key)
        {
            FileStream fp = new FileStream(fileLocation, FileMode.Open, FileAccess.Read);
            FileStream encryptedFile = new FileStream(encryptedFileLocation, FileMode.Create);

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.Mode = CipherMode.ECB;
                aes.Padding = PaddingMode.PKCS7;

                ICryptoTransform encryptor = aes.CreateEncryptor(Encoding.UTF8.GetBytes("asdfasdfasdfasdf"), Encoding.UTF8.GetBytes("fdsafdsafdsafdsa"));
                CryptoStream cryptoStream = new CryptoStream(encryptedFile, encryptor, CryptoStreamMode.Write);

                byte[] buffer = new byte[1024];
                int read;

                try
                {
                    while((read = fp.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        cryptoStream.Write(buffer, 0, read);
                        cryptoStream.FlushFinalBlock();
                    }
                } 
                catch(Exception e)
                {

                }
                finally
                {
                    fp.Close();
                    encryptedFile.Close();
                }

            }
        }

        public static void decrypt(string cypherFileLocation, string decryptedFileLocation, string key)
        {
            FileStream fp = new FileStream(cypherFileLocation, FileMode.Open, FileAccess.Read);
            FileStream decryptedFile = new FileStream(decryptedFileLocation, FileMode.Create);


            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.Mode = CipherMode.ECB;
                aes.Padding = PaddingMode.PKCS7;

                ICryptoTransform decryptor = aes.CreateDecryptor(Encoding.UTF8.GetBytes("asdfasdfasdfasdf"), Encoding.UTF8.GetBytes("fdsafdsafdsafdsa"));
                CryptoStream cryptoStream = new CryptoStream(fp, decryptor, CryptoStreamMode.Read);

                try
                {
                    byte[] buffer = new byte[1024];
                    int read;
                    while((read = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        decryptedFile.Write(buffer, 0, read);
                        decryptedFile.Flush();
                    }
                }
                catch(Exception e)
                {

                }
                finally
                {
                    fp.Close();
                    decryptedFile.Close();
                }
            }
        }

正如我在上面的评论中所述,您的代码中存在一个不可见的错误,因为您使用空的 catch 块隐藏了异常。异常是 NotSupportedException,消息是

FlushFinalBlock() method was called twice on a CryptoStream. It can only be called once

对于长度小于 1024 字节的文本文件,加密工作正常,但任何更大的文件(也包括文本文件)都会崩溃,因为代码会尝试调用两次或更多次 cryptoStream.FlushFinalBlock();

所以,我已经测试了对您的代码所做的更改并且它有效

try
{
    while ((read = fp.Read(buffer, 0, buffer.Length)) > 0)
    {
        cryptoStream.Write(buffer, 0, read);
    }
    // Moved outside the loop
    cryptoStream.FlushFinalBlock();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}
finally
{
    fp.Close();
    encryptedFile.Close();
}

在解密例程中,您还在循环内调用了 Flush,这不是必需的,可以移到循环外。但在这种情况下,没有可见的错误。无论如何,不​​要隐藏异常,它们对于理解和修复错误至关重要。