我正在使用“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;
}
答案 0 :(得分:1)
它告诉你,它没有办法接受这7个字符并对它们执行任何有意义的转换 - 它无法执行任何使用它们的解密。
在尝试解密之前执行长度检查,或捕获异常;在任何一种情况下,只需走下你的路线,就会收到一个无效的令牌"逻辑。
答案 1 :(得分: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();
}
}
}
答案 2 :(得分:0)
保存加密字符串的长度,然后检查长度是否相同。如果是,则继续调用解密方法。