如何使用 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,这不是必需的,可以移到循环外。但在这种情况下,没有可见的错误。无论如何,不要隐藏异常,它们对于理解和修复错误至关重要。
我正在尝试 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,这不是必需的,可以移到循环外。但在这种情况下,没有可见的错误。无论如何,不要隐藏异常,它们对于理解和修复错误至关重要。