0

我正在使用“AesManaged”对 Web 应用程序中的受保护数据进行加密和解密。在我的场景中,我在用户登录时基于“Email + CurrentDate”创建一个令牌,并以加密格式将其发送回用户(使用 AESManaged 类完成加密),并且当用户调用下一个服务器端方法时,例如“显示报告”,用户/客户端应用程序还将随请求发送该加密令牌。在服务器端我解密令牌,并在基于解密令牌执行条件逻辑之后,决定给定用户是否有权访问此方法(一种授权检查)。

用户提供从服务器获得的正确加密字符串或长度相同但用户替换加密字符串中的字符的基本流程表现良好(如预期)。

但是,当用户得到一个(例如)54 个字符的字符串但只向服务器发送 7 个字符时,问题就出现了。然后发生以下异常。

即使用户提供无效数据,我也想避免此异常。所以,基本上字符串应该总是被解密,如果它是无效的令牌,那么我可以限制对资源的访问。我怎样才能做到这一点?您的回答将不胜感激。

异常详情:

发生异常的特定代码块。

 // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

例外:“要解密的数据长度无效。”

异常详情:

目标站点:{Byte[] TransformFinalBlock(Byte[], Int32, Int32)}

声明类型:{Name = "RijndaelManagedTransform" FullName = "System.Security.Cryptography.RijndaelManagedTransform"}

名称: TransformFinalBlock

注意:我为加密和解密方法提供相同的密钥和 iv。

代码:

public string EncryptAuthenticationTokenAes(string plainText, byte[] Key, byte[] IV)
        {


            byte[] encrypted;
            // Create an AesManaged object
            // with the specified key and IV.
            using (AesManaged aesAlg = new AesManaged())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;


                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }
            // Return the encrypted bytes from the memory stream.
            return Convert.ToBase64String(encrypted);

        }

        public string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV)
        {
            // becuase it is base64, if mod4>0 then it is consider as invalid token
            int mod4 = encryptedString.Length % 4;
            if (mod4 > 0)
            {
                return string.Empty;
            }
            byte[] cipherText = Convert.FromBase64String(encryptedString);
            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an AesManaged object
            // with the specified key and IV.
            using (AesManaged aesAlg = new AesManaged())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;
        }
4

3 回答 3

1

它告诉您,它无法获取这 7 个字符并对它们执行任何有意义的转换 - 它无法使用它们执行任何类型的解密。

在尝试解密之前执行长度检查,或者捕获异常;在任何一种情况下,只需按照“收到无效令牌”的逻辑进行即可。

于 2012-05-14T06:41:41.550 回答
0

试试这个

           // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        if (encryptedString.Length != aesAlg.BlockSize)
                        {
                            // Handle invalid token here.
                        }
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
于 2012-05-14T07:11:27.073 回答
0

保存加密字符串的长度,然后检查长度是否相同。如果是,则继续调用解密方法。

于 2012-05-27T10:49:28.943 回答