c# - 解密前如何保护加密文件不被破坏

标签 c# vb.net encryption cryptography rijndael

我正在使用 Rijndael 算法加密 pdf 文件。加密和解密工作正常。加密会将 pdf 文件转换为具有 .key 扩展名的文件。

问题是我可以在记事本中打开这个文件(它显示一些 Unicode 字符)并损坏它。考虑以下场景:

我已打开文件并删除一些字符/添加一些字符保存记事本文件。如果我将这个文件传递给解密方法,我将得到损坏的文件作为输出。我知道这是因为在文件中添加或删除字符时 byteStream 发生变化(填充更改)。

这是我的问题:

有什么办法可以解决这个问题吗?换句话说,禁用对加密文件的编辑?**

以下是我使用的加密方法,

VB代码

   Dim plainFile As String = basePath & "\cryptoText.pdf"
   Dim password As String = "somePass"
   Dim UE As New UnicodeEncoding()
   Dim key As Byte() = UE.GetBytes(password)
   Dim cryptFile As String = basePath & "\cryptoText.key"
   Dim fsCrypt As New FileStream(cryptFile, FileMode.Create)
   Dim RMCrypto As New RijndaelManaged()
   Using csKey As New CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)
         Dim FsIn As New FileStream(plainFile, FileMode.Open)
         Dim data As Integer
         While (data = FsIn.ReadByte()) <> -1
                csKey.WriteByte(CByte(data))
         End While
         FsIn.Close()
    End Using
    fsCrypt.Close()

C#代码

    string plainFile = basePath + "\\cryptoText.pdf";
    string password = "somePass";
    UnicodeEncoding UE = new UnicodeEncoding();
    byte[] key = UE.GetBytes(password);
    string cryptFile = basePath + "\\cryptoText.key";
    FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
    RijndaelManaged RMCrypto = new RijndaelManaged();
    using (CryptoStream csKey = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)) {
        FileStream FsIn = new FileStream(plainFile, FileMode.Open);
        int data = 0;
        while ((data == FsIn.ReadByte()) != -1) {
            csKey.WriteByte(Convert.ToByte(data));
        }
        FsIn.Close();
    }
    fsCrypt.Close();

注意:我已经在 c# 和 vb.net 中都尝试过了,所以我将我的问题标记为两者。

最佳答案

答案是做两件事,

  1. 加密,
  2. 在加密数据上向其添加一个 HMAC(如使用相同 key 的 SHA256),并将其附加到密码流的末尾

https://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256%28v=vs.110%29.aspx

然后当你解密的时候,你

  1. 验证 HMAC 是否有效,
  2. IFF#1 验证,然后才解密

此外,如果这不是本地文件而是某种网络流,那么您必须在恒定时间内进行验证 - 您不能使用正常的字节比较功能。这是因为定时攻击。但是对于本地文件,你可以做任何你喜欢的比较,因为没有时间攻击。

关于c# - 解密前如何保护加密文件不被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32409753/

相关文章:

c# - LINQ to SQL 查询返回重复项

c# - HLSL 和 XNA : How do I get the position and color of surrounding pixels of the current pixel shader iteration?

c# - 带有 C# .NET 4.5 的 XNA 4.0?

c# - 将 HttpWebResponse 转换为 HttpResponse

ios - 在浏览器中打开 Realm 文件总是需要加密 key

c# - 已成功与服务器建立连接,但在登录过程中出现错误。目标主体名称不正确

c# - 无状态(在谷歌代码上)和 Windows 工作流之间的比较

正则表达式 HTML 帮助

vb.net - 如何检查测验答案是否正确?

security - 使用 Ansible 自动部署 SSL 私钥