c# - 如何使用 AES 加密文本文件以外的文件?PDF、Word 等
问题描述
我正在尝试在 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() 方法在 CryptoStream 上被调用了两次。只能调用一次
加密适用于长度小于 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 ,这不是必需的,可以移到循环外。但在这种情况下,没有可见的错误。无论如何,不要隐藏异常,它们对于理解和修复错误至关重要。
推荐阅读
- mpi - 使用 open-mpi 时的链接问题(使用包装器)
- fiddler - 如何在 fiddleScript 中创建 json 对象并发送 http post
- xcode - X Code 无法归档颤振项目
- scala - 如何将地图转换为 spark scala 中的各个列?
- html - 我的 CSS 导航栏的背景颜色属性不起作用
- php - 将数据更新到php中的数据库后,为保存和提交显示相同的消息
- python - 如何解决错误:Poetry 未使用推荐的安装程序安装。无法自动更新
- microservices - Consul 数据中心:前一个领导节点失败后没有自动选择领导节点
- javascript - undefined 不是 onPress 的对象(评估 this.props.navigation.navigate)
- mysql - 我想在mysql中对日期进行排序