C#Rijandel文件解密填充无效,无法删除

时间:2017-03-11 14:01:16

标签: c# encryption padding

我想从单个文件流加密文件,但是当解密填充无效且无法删除时我遇到此错误但是如果我设置padding,则加密和解密方法具有相同的填充.Zeros不加密文件

  private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("TestKey", SALT);
    public bool EncryptFileP(string Path)
    {
        FileInfo IOF = new FileInfo(Path);
        WRStream = new FileStream(Path, FileMode.Open);

        CryptoStream cryptoStream;
        Rijndael rijndael = Rijndael.Create();

        rijndael.Key = pdb.GetBytes(16);
        rijndael.IV = pdb.GetBytes(16);

        rijndael.Mode = CipherMode.CBC;
        rijndael.Padding = PaddingMode.PKCS7;

        cryptoStream = new CryptoStream(WRStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);

        cryptoStream.Close();
        WRStream.Close();

        return true;
    }
    public bool DecryptFileP(string Path)
    {
        FileInfo IOF = new FileInfo(Path);
        WRStream = new FileStream(Path, FileMode.Open);

        CryptoStream cryptoStream;
        Rijndael rijndael = Rijndael.Create();

        rijndael.Key = pdb.GetBytes(16);
        rijndael.IV = pdb.GetBytes(16);

        rijndael.Mode = CipherMode.CBC;
        rijndael.Padding = PaddingMode.PKCS7;

        cryptoStream = new CryptoStream(WRStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);

        cryptoStream.Close(); //error! padding is invalid and cannot be removed 
        WRStream.Close();


        return true;
    }

2 个答案:

答案 0 :(得分:2)

在我看来,您正在缺少从正在创建的流中读取和写入的内容。

在某些时候加密文件,您需要将要加密的plaint-text数据写入cryptoStream中的EncryptFileP,同样,当您解密时,您需要回读在cryptoStream中的DecryptFileP之外。这些流不会像您正在尝试的那样加密/解密文件

答案 1 :(得分:0)

您必须分别为加密和解密实例化Rfc2898DeriveBytes,因为它是有状态的。将Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("TestKey", SALT);移至EncryptFilePDecryptFileP

安全提示:

IV必须是不可预测的(读:随机)。不要使用静态IV,因为这会使密码具有确定性,因此在语义上不安全。观察密文的攻击者可以确定何时发送相同的消息前缀。 IV不是秘密,因此您可以将其与密文一起发送。通常,它只是在密文之前预先填写并在解密之前切掉。

最好对您的密文进行身份验证,以便像padding oracle attack这样的攻击是不可能的。这可以使用经过身份验证的模式(如GCM或EAX)或encrypt-then-MAC方案来完成。