我想从单个文件流加密文件,但是当解密填充无效且无法删除时我遇到此错误但是如果我设置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;
}
答案 0 :(得分:2)
在我看来,您正在缺少从正在创建的流中读取和写入的内容。
在某些时候加密文件,您需要将要加密的plaint-text数据写入cryptoStream
中的EncryptFileP
,同样,当您解密时,您需要回读在cryptoStream
中的DecryptFileP
之外。这些流不会像您正在尝试的那样加密/解密文件
答案 1 :(得分:0)
您必须分别为加密和解密实例化Rfc2898DeriveBytes
,因为它是有状态的。将Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("TestKey", SALT);
移至EncryptFileP
和DecryptFileP
。
安全提示:
IV必须是不可预测的(读:随机)。不要使用静态IV,因为这会使密码具有确定性,因此在语义上不安全。观察密文的攻击者可以确定何时发送相同的消息前缀。 IV不是秘密,因此您可以将其与密文一起发送。通常,它只是在密文之前预先填写并在解密之前切掉。
最好对您的密文进行身份验证,以便像padding oracle attack这样的攻击是不可能的。这可以使用经过身份验证的模式(如GCM或EAX)或encrypt-then-MAC方案来完成。