C# 填充字符出现时的解密问题

C# 填充字符出现时的解密问题,c#,encryption,aes,C#,Encryption,Aes,我在文本框中输入存档的名称以获取此存档的消息 我把密码写在一个文本框里 我计算盐 按钮点击 private void button1_Click_1(object sender, EventArgs e) { String message; String password; String result; String resultSalt; String nameResult; byt

我在文本框中输入存档的名称以获取此存档的消息

我把密码写在一个文本框里

我计算盐

按钮点击

    private void button1_Click_1(object sender, EventArgs e)
    {
        String message;
        String password;
        String result;
        String resultSalt;
        String nameResult;
        byte[] salt;


        password = textBox2.Text;
        nameResult = textBox3.Text;
        new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]);

        resultSalt = Convert.ToBase64String(salt);

        if (radioButton1.Checked == true)
        {
            message = readArchive();
            result = Encrypt(message,password,resultSalt);
            try
            {
                File.WriteAllText(nameResult, result);
                MessageBox.Show("Encrypt Ok");
            }
            catch
            {
                MessageBox.Show("Error");
            }

        }
        else
        {
            message = readArchive();
            result = Decrypt(message,password,result);
            try
            {
                File.WriteAllText(nameResult, resultSalt);
                MessageBox.Show("Decrypt OK");
            }
            catch
            {
                MessageBox.Show("Error");
            }

        }
    }
方法加密

    public static string Encrypt(string message, string pass, string salt)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        DeriveBytes rgb = new Rfc2898DeriveBytes(pass, Encoding.Unicode.GetBytes(salt), 9);
        byte[] key = rgb.GetBytes(aes.KeySize >> 3);
        byte[] iv = rgb.GetBytes(aes.BlockSize >> 3);
        aes.Mode = CipherMode.CBC;
        aes.Key = key;
        aes.IV = iv;
        ICryptoTransform encryptor = aes.CreateEncryptor();
        byte[] data = Encoding.Unicode.GetBytes(message);
        byte[] dataencrypt = encryptor.TransformFinalBlock(data, 0, data.Length);
        return Convert.ToBase64String(dataencrypt);
    }
方法解密

    public static string Decrypt(string message, string pass, string salt)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        DeriveBytes rgb = new Rfc2898DeriveBytes(pass, Encoding.Unicode.GetBytes(salt), 9);
        byte[] key = rgb.GetBytes(aes.KeySize >> 3);
        byte[] iv = rgb.GetBytes(aes.BlockSize >> 3);
        aes.Mode = CipherMode.CBC;
        aes.Key = key;
        aes.IV = iv;
        ICryptoTransform decryptor = aes.CreateDecryptor();
        byte[] data = Convert.FromBase64String(message);
        byte[] datadecrypt = decryptor.TransformFinalBlock(data, 0, data.Length);
        return Encoding.Unicode.GetString(datadecrypt);
    }
方法readArchive

    private string readArchive()
    {
        String nameArchive = textBox1.Text;
        String text = "";
        try
        {

            text = File.ReadAllText(@nameArchive);

        }
        catch
        {

            MessageBox.Show("Error.");
        }
        return text;
    }
误差线

byte[] datadecrypt = decryptor.TransformFinalBlock(data, 0, data.Length);
System.Core.dll中类型为“System.Security.Cryptography.CryptographyException”的未处理异常

其他信息:字符之间的填充无效,无法删除


在将salt传递给您的
加密(…)
之前,请使用以下命令对salt进行base64编码:
resultSalt=Convert.ToBase64String(salt)
,然后使用
encoding.Unicode.GetBytes(salt)
获取base64编码字符串的字节值。这可能不是您想要的,而是将其作为字节[]传递,或者在使用它之前执行正确的base64解码


但这不是主要问题。。主要问题是将
结果
传递给
解密(…)
而不是
resultSalt
。但是当您这样做时,您需要确保它与在
加密(..)
上使用的相同。。当前,每次单击都会生成一个新的salt。

需要更多信息。异常消息是什么?它有任何内部异常吗?它是什么?
Unicode。GetBytes(salt)
很弱,但它必须匹配加密。写一个完整的密码,包含解密和加密代码。填充模式也应该匹配加密上的模式。但很可能您在线路的某个地方损坏了Base64。几乎没有例外,填充错误意味着由于输入不正确而导致解密失败。这解决了我的问题