C# 使用Rijndael数据加密和解密的时间过长

C# 使用Rijndael数据加密和解密的时间过长,c#,.net,security,aes,rijndael,C#,.net,Security,Aes,Rijndael,我正试图让这段代码进行加密和解密,但在.FlushFinalBlock()期间解密时,我得到的数据长度太长 我不确定我在这里做错了什么,因为我在这个问题上没有把握 有人能告诉我我做错了什么吗?加密是可以的,但它无法解密其加密 static byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 }; public static

我正试图让这段代码进行加密和解密,但在
.FlushFinalBlock()
期间解密时,我得到的数据长度太长

我不确定我在这里做错了什么,因为我在这个问题上没有把握

有人能告诉我我做错了什么吗?加密是可以的,但它无法解密其加密

   static byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 };

   public static string Encrypt(string data, string password)
    {
        //
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);
        //
        Rijndael i_Alg = Rijndael.Create();
        i_Alg.Padding = PaddingMode.None;
        i_Alg.Key = pdb.GetBytes(32);
        i_Alg.IV = pdb.GetBytes(16);
        //
        using (var cryptoProvider = new DESCryptoServiceProvider())
        using (var memoryStream = new MemoryStream())
        using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateEncryptor(), CryptoStreamMode.Write))
        using (var writer = new StreamWriter(cryptoStream))
        {
            writer.Write(data);
            writer.Flush();
            cryptoStream.FlushFinalBlock();
            writer.Flush();
            return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
    }
    public static string Decrypt(string data, string password)
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);
        //
        Rijndael i_Alg = Rijndael.Create();
        i_Alg.Padding = PaddingMode.None;
        i_Alg.Key = pdb.GetBytes(32);
        i_Alg.IV = pdb.GetBytes(16);
        //
        using (var cryptoProvider = new DESCryptoServiceProvider())
        using (var memoryStream = new MemoryStream())
        using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateDecryptor(), CryptoStreamMode.Write))
        using (var writer = new StreamWriter(cryptoStream))
        {
            writer.Write(data);
            writer.Flush();
            cryptoStream.FlushFinalBlock();
            writer.Flush();
            return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
    }

您的代码有一些问题。首先,您要创建一个Rijndael(AES)对象。但是,您使用的是
DESCryptoServiceProvider
,这意味着您实际使用的是DES,而不是Rijndael。因此,您还存在一个问题,即您没有为算法设置密钥。下面是使用
RijndaelManaged
算法重新编写的两个函数,该算法是.NET上
AES
算法的托管实现。我已经测试过了,你可以毫无问题地加密和解密。另外:不要使用盐的价值,它在互联网上到处都是

static byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 };

public static string EncryptString(string plainText, string password)
{
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);
    using (RijndaelManaged i_Alg = new RijndaelManaged { Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) })
    {
        using (var memoryStream = new MemoryStream())
        using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateEncryptor(), CryptoStreamMode.Write))
        {
            byte[] data = Encoding.UTF8.GetBytes(plainText);
            cryptoStream.Write(data, 0, data.Length);
            cryptoStream.FlushFinalBlock();

            return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
    }
}

public static string Decrypt(string cipherText, string password)
{
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);

    using (RijndaelManaged i_Alg = new RijndaelManaged { Padding = PaddingMode.Zeros, Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) })
    {
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateDecryptor(), CryptoStreamMode.Write))
            {
                byte[] data = Convert.FromBase64String(cipherText);
                cryptoStream.Write(data, 0, data.Length);
                cryptoStream.Flush();

                return Encoding.UTF8.GetString(memoryStream.ToArray());
            }
        }
    }
}

要生成一个随机salt,我将使用,这将生成一个加密安全的随机字节数组,您可以使用它。您需要在单独的过程中生成它,并将其用作盐。

伙计,这太完美了!喜欢这个扩展。。谢谢你。有没有资源可以让我演示如何选择正确的salt值?我编辑了答案,以添加有关生成随机salt的信息。老实说,我的首选方法是只使用RNGCryptoServiceProvider生成一个随机密钥,而不使用Rfc2898DeriveBytes。如果你使用的是随机密钥,我认为没有必要。您需要做的唯一额外的事情是对照可能存在的任何弱键检查输出。原因是Rfc2898DeriveBytes将使用Sha-1 HMAC,使用您的密码作为密钥,然后散列salt,这样您可能会减少密钥空间,因为Sha-1输出160位,而AES最多可以占用256位密钥。