使用相同参数的加密会产生不同的结果

时间:2016-12-20 12:49:34

标签: c# encryption aes

我确定我在这里犯了很大的错误......

我正在尝试使用AES加密字符串,但每次传递相同的参数(plainText,password和salt)会产生不同的结果。

我打电话如下,每个人的结果不同:

var cipherTextCode  = EncryptAes(plainTextCode, "K29V2NVsFhCVRYeJ88PJSdBd8Gd1PEXnWsX3lCKcy0y4M43oRq", "LQzJUNdsVgio20KnOPTdMONBO50FCCgOLXK5s7vpeX3Pr3fOu1");
var cipherTextCode1 = EncryptAes(plainTextCode, "K29V2NVsFhCVRYeJ88PJSdBd8Gd1PEXnWsX3lCKcy0y4M43oRq", "LQzJUNdsVgio20KnOPTdMONBO50FCCgOLXK5s7vpeX3Pr3fOu1");
var cipherTextCode2 = EncryptAes(plainTextCode, "K29V2NVsFhCVRYeJ88PJSdBd8Gd1PEXnWsX3lCKcy0y4M43oRq", "LQzJUNdsVgio20KnOPTdMONBO50FCCgOLXK5s7vpeX3Pr3fOu1");
var cipherTextCode3 = EncryptAes(plainTextCode, "K29V2NVsFhCVRYeJ88PJSdBd8Gd1PEXnWsX3lCKcy0y4M43oRq", "LQzJUNdsVgio20KnOPTdMONBO50FCCgOLXK5s7vpeX3Pr3fOu1");

我用来加密的方法如下:

     private const int CB = 32;

   /// <summary>
        /// The initialization vector
        /// </summary>
        private readonly byte[] InitialisationVectorBytes = Encoding.ASCII.GetBytes("EAzjVfNrCzOoE7AI");

/// <summary>
        /// Encrypts a string using AES encryption
        /// </summary>
        /// <param name="plainText">The string to encrypt</param>
        /// <param name="passPhrase">The encryption key</param>
        /// <param name="salt">The encryption salt</param>
        /// <returns>an encrypted string</returns>
        private string EncryptAes(string plainText, string passPhrase, string salt)
        {
            try
            {
                //get the plain text bytes and the salt bytes
                var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
                var saltBytes = Encoding.UTF8.GetBytes(salt);

                //Derives the key from the phrase and the salt
                using(var password = new Rfc2898DeriveBytes(passPhrase, saltBytes))
                {
                    //use the AES Rijndael algorithm
                    using(var symmetricKey = new RijndaelManaged())
                    {
                        //set the mode
                        symmetricKey.Mode = CipherMode.CBC;

                        //create an encryption object
                        using(var encryptor = symmetricKey.CreateEncryptor(password.GetBytes(CB), InitialisationVectorBytes))
                        {
                            //create a memory stream
                            using(var memoryStream = new MemoryStream())
                            {
                                //create a cryptography stream
                                using(var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                                {
                                    //encrypt the plain text
                                    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                                    cryptoStream.FlushFinalBlock();
                                    var cipherTextBytes = memoryStream.ToArray();
                                    return Convert.ToBase64String(cipherTextBytes);
                                }
                            }
                        }
                    }
                }
            }
            catch(SecurityException)
            {
                return string.Empty;
            }
        }

我做错了什么?

1 个答案:

答案 0 :(得分:-6)

像AES这样的阻塞是一种键控排列。在AES的情况下,它需要一个密钥,然后确定地将一个16字节的块转换为另一个16字节的块。

要使用分组密码加密某些内容,您需要使用某种操作模式。通常,这些模式采用IV(类似于盐),对于您加密的每条消息,它应该是不同的。 IV中的这种差异导致完全不同的加密消息。使用相同的IV和密钥加密相同的消息将始终返回相同的密文。使用相同的IV和密钥加密多个消息会削弱安全性,但是取决于模式的多少。

IV所需的属性取决于所选择的模式,有时它需要是唯一的(例如对于CTR模式),有时它需要是不可预测的随机的(例如对于CBC模式)。但它通常不一定要保密,所以你将它与密文一起发送给收件人,通常作为前缀。

有一些模式专为确定性加密而设计。使用这些模式,如果两条消息相同,您仍然会泄漏,但仅此而已。只有在需要确定性时才应使用这些模式。

简而言之:您正在使用“symmetricKey.Mode = CipherMode.CBC;” :不可预测的随意。

如果你想要它,你可以使用:CipherMode.CTR

信用:my source