日志文件,“填充无效,无法删除”

时间:2015-10-21 08:53:24

标签: c# .net encryption cryptography

我在错误日志文件中找到了这个,但网站仍然正常工作。我无法重现这个问题,我仍然担心它,因为我在错误日志中看到这种情况经常发生。

任何人都有导致错误的原因?

public static string Decrypt(string inputText)
{
    if (String.IsNullOrEmpty(inputText))
        return string.Empty;
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    byte[] encryptedData = Convert.FromBase64String(inputText);
    PasswordDeriveBytes secretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, SALT);

    using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
    {
        using (MemoryStream memoryStream = new MemoryStream(encryptedData))
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
            {
                byte[] plainText = new byte[encryptedData.Length];
                int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
                return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
            }
        }
    }
}

错误抛出

下面的一行
return Encoding.Unicode.GetString(plainText, 0, decryptedCount);

这就是错误日志中的内容

  

System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.
   at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
   at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
   at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at QueryStringModule.Decrypt(String inputText) in line 135
   at QueryStringModule.context_BeginRequest(Object sender, EventArgs e) in E:\SSv45\Pages\QueryStringModule.cs:line 46
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

由于 明飞

2 个答案:

答案 0 :(得分:2)

是的,您应该担心,由于多种原因,主要原因是您的数据当然没有被解密。

但是查看代码还有很多值得担心的问题:

  1. 对于网站,应使用URL-safe base 64来避免随机解密错误;
  2. 加密密钥和salt似乎是不变的,在这种情况下,使用PasswordDeriveBytes不是必需的,只提供错误保护+不必要的减速;
  3. 密钥和IV将是静态的,因此您可以区分密文;
  4. 对于超过20个字节的数据,
  5. PasswordDeriveBytes不安全,甚至可能在IV中重复密钥的字节;
  6. Read方法可能不会返回所有数据字节;
  7. 它使用Unicode编码,在Microsoft的情况下意味着UTF-16LE,基本上需要两倍于普通文本的字节;
  8. 没有明确的错误处理或区分系统异常和输入相关的异常。
  9. 你不应该通过网络连接使用CBC,因为填充oracle攻击,中间的人是可能的。 您的“加密”数据可能不保密!。如果有很多很多关于这个的日志,那么有人可能会在我们发言时解密你的密文。

    基本上,此代码设法跳入每个可用的可用坑。您遇到的问题可能是#1或#5。

    然而,你应该创建一个完整的代码重新设计,最好由知道他/她正在做什么的人。

答案 1 :(得分:1)

您的代码使用的是Rijndael,它是一个块密码,意味着它以16个字符块(128位块)加密数据。

如果加密数据的最后一块不够长(<128位),则必须添加填充以确保它是可加密的。

如果在加密期间明确设置填充,则需要确保在解密期间明确设置填充。 如果您没有在加密过程中明确设置它,那么您无需在解密期间明确设置它 - 只需确保两种方法匹配。

如果加密时使用的密钥与用于解密的密钥不同,也会出现此错误。