【问题标题】:Get IV from Encrypted text to use in decrypt method从加密文本中获取 IV 以用于解密方法
【发布时间】:2019-03-13 08:58:32
【问题描述】:

我正在尝试使用 AES256 算法进行加密和解密,我有以下代码。

 public string Encrypt(string dataToEncrypt, string key)
            {
                if (dataToEncrypt == null || dataToEncrypt.Length <= 0)
                    throw new ArgumentNullException("plainText");
                if (key == null || key.Length <= 0)
                    throw new ArgumentNullException("Key");
                var iv = GenerateRandomNumber(16);
                using (var aes = new AesCryptoServiceProvider())
                {
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;
                    aes.Key = Convert.FromBase64String(key);
                    aes.IV = iv;
                    byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
                    using (var memoryStream = new MemoryStream())
                    {
                        var cryptoStream = new CryptoStream(memoryStream, 
                       aes.CreateEncryptor(),
                            CryptoStreamMode.Write);
                        cryptoStream.Write(data, 0, data.Length);
                        cryptoStream.FlushFinalBlock();                    
                        return Convert.ToBase64String(memoryStream.ToArray());
                    }
                }
            }
  public string DecryptReturnsString(string dataToDecrypt, string key)
        {
            if (dataToDecrypt == null || dataToDecrypt.Length <= 0)
                throw new ArgumentNullException("dataToDecrypt");

            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");

            using (var aes = new AesCryptoServiceProvider())
            {
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;
                aes.Key = Convert.FromBase64String(key);
                byte[] data= Convert.FromBase64String(dataToDecrypt);
                aes.IV = getIV(data);
                using (var memoryStream = new MemoryStream())
                {
                    var cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(),
                        CryptoStreamMode.Write);

                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();

                    var decryptBytes = Encoding.UTF8.GetString(memoryStream.ToArray());

                    return decryptBytes;
                }
            }
        }

   public byte[] GenerateRandomNumber(int length)
        {
            using (var randomNumberGenerator = new RNGCryptoServiceProvider())
            {
                var randomNumber = new byte[length];
                randomNumberGenerator.GetBytes(randomNumber);

                return randomNumber;
            }
        }
        private static byte[] getIV(byte[] arr)
        {
            byte[] IV = new byte[16];
            Array.Copy(arr, 0, IV, 0, 16);
            return IV;
        }

这里我试图从加密字符串中获取IV,但是当我调试时最初生成的IV和提取的IV不同,所以它给了我这个异常,“填充无效,无法删除。”

谁能看看我的 GetIV() 方法,让我知道我哪里做错了。

【问题讨论】:

  • 您无法从加密文本中获取 IV。你需要想出一些其他的方法来传递它。把它当作加密密钥的一部分;它是应该安全传输的随机值。
  • IV 不一定是秘密的。它更类似于哈希的盐,它必须是随机且唯一的,但如果我理解正确,不一定是秘密的。见security.stackexchange.com/questions/17044/…
  • 保存 IV 的常用方法是将其添加到加密文本之前。因此,只需在加密时将其写入您的memoryStream。然后你可以在解密时阅读它。
  • 旁注:AesCryptoServiceProvider 有一个名为GenerateIV() 的预定义方法。没有理由自己重建该功能。

标签: c# asp.net encryption cryptography aes


【解决方案1】:

有两个问题。

  1. 似乎您没有在密文中发送 IV(它本身并没有完成)。常见的做法是在密文前面加上 IV。因此,正如罗伯特所评论的,您可以在加密之前直接将 IV 写入内存流

  2. 解密时,您可以读取 IV(data 的第一个字节,但仅解密其余部分(子数组 16 .. length )

【讨论】:

    【解决方案2】:

    在 CBC 操作模式下的 IV 必须以未加密的形式发送,否则,您无法解密第一个块,其余的可以解密。这不存在安全问题。对于 CBC 而言,IV 的关键在于它必须是不可预测的。

    正如罗伯特所说,将其添加到流的开头。

    see

    var mergedStream = new MergedStream(new Stream 
    {
        new MemoryStream(iv),
        cryptoStream,
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 2023-04-06
      • 2019-07-22
      • 2013-06-07
      相关资源
      最近更新 更多