简体   繁体   English

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

[英]C# Rijandel File Decryption padding is invalid and cannot be removed

i want to encrypt file from single file stream but i got this error when decryption padding is invalid and cannot be removed but Encryption and Decryption method has same padding if i set padding.Zeros does not encrypt file 我想从单个文件流中加密文件,但是当解密填充无效且无法删除时出现此错误,但是如果我设置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;
    }

Looks to me like you are missing reading and writing from the streams you are creating. 在我看来,您正在丢失正在创建的流中的读写。

At some point to encrypt a file, you will need to write the plaint-text data you want to encrypt to cryptoStream in your EncryptFileP , and similarly, when you decrypt you need to read back out of cryptoStream in DecryptFileP . 在某个时刻加密文件,您将需要将要加密的纯文本数据写入cryptoStream中的EncryptFileP ,类似地,解密时,您需要从cryptoStream中读出DecryptFileP These streams won't encrypt/decrypt a file in place like it appears you are trying to do 这些流不会像您尝试执行的操作那样就地加密/解密文件

You have to instantiate Rfc2898DeriveBytes separately for encryption and decryption, because it is stateful. 您必须分别实例化Rfc2898DeriveBytes进行加密和解密,因为它是有状态的。 Move Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("TestKey", SALT); 移动Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("TestKey", SALT); into EncryptFileP and DecryptFileP . 进入EncryptFilePDecryptFileP


Security hints: 安全提示:

The IV must be unpredictable (read: random). IV必须是不可预测的(读取:随机)。 Don't use a static IV, because that makes the cipher deterministic and therefore not semantically secure. 不要使用静态IV,因为这会使密码具有确定性,因此在语义上也不安全。 An attacker who observes ciphertexts can determine when the same message prefix was sent before. 观察密文的攻击者可以确定以前何时发送相同的消息前缀。 The IV is not secret, so you can send it along with the ciphertext. IV不是秘密的,因此您可以将其与密文一起发送。 Usually, it is simply prepended to the ciphertext and sliced off before decryption. 通常,它只是简单地加在密文之前,并在解密之前将其切开。

It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. 最好对您的密文进行身份验证,这样就不可能进行像填充oracle攻击之类的攻击 This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme. 这可以通过GCM或EAX之类的经过身份验证的模式来完成,也可以通过先加密后MAC方案来完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM