在我的 ASP.NET WebForms 应用程序中(该应用程序在 windows server 2008 R2、IIS 7.5 和 Runtime v4.0 集成模式应用程序池上运行),我正在加密数据,将其放在 QueryString 上并使用System.Security.Cryptography.SymmetricAlgorithm
类解密数据。但是我偶尔会在解密数据时遇到一些问题,我得到以下异常;
不良数据。
说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。
异常详细信息:System.Security.Cryptography.CryptographicException:错误数据。
源错误:
在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。
堆栈跟踪:
[加密异常:错误数据。]
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +33
System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone) +0
System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +313
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +33 Cryptography35.SymmetricEncryptionUtility.DecryptData(Byte[] data, String keyFile) 在 E:\Documents\@Library\Cryptography35\Cryptography35\SymmetricEncryptionUtility.cs:124 Cryptography35.SymmetricQueryString.SymmetriclyEncryptedQueryString ..ctor(String encryptedData, String keyfilename, String algorithmname) 在 E:\Documents\@Library\Cryptography35\Cryptography35\SymmetricQueryString\SymmetriclyEncryptedQueryString.cs:67 WebForms.Web.Views.purchase_a.GetSymmetriclyEncryptedQueryString() 在 E:\Documents\ WebForms.Web\Views\purchase-a.aspx.cs:35 WebForms.Web.Views.purchase_a.Page_Load(Object sender, EventArgs e) 在 E:\Documents\WebForms.Web\Views\purchase-a.aspx.cs :56 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,对象 o,对象 t,EventArgs e) +14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207 版本信息:微软.NET 框架版本:4.0.30319;ASP.NET 版本:4.0.30319.1
正如我所指出的,我有时会收到此错误,而不是每次运行时都会收到此错误。我不知道我在哪里做错了(在加密阶段或解密阶段)这是我用来做的代码;
private SymmetriclyEncryptedQueryString GetSymmetriclyEncryptedQueryString() {
#region _decrypting the value
string KeyFileName;
string AlgorithmName = "DES";
Cryptography35.SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
KeyFileName = HttpContext.Current.Server.MapPath("~/@config/") + "\\symmetric_key.config";
#endregion
#region _reading and assigning the value
if (Request.QueryString["q"] == null)
throw new NullReferenceException("QueryString value is null on search result page");
SymmetriclyEncryptedQueryString QueryString = new SymmetriclyEncryptedQueryString(Request.QueryString["q"], KeyFileName, AlgorithmName);
#endregion
return QueryString;
}
SymmetriclyEncryptedQueryString
班级
public class SymmetriclyEncryptedQueryString : System.Collections.Specialized.StringDictionary {
public string KeyFileName { get; set; }
public string AlgorithmName { get; set; }
/// <summary>
/// Use this for encrypte the value
/// </summary>
/// <param name="keyfilename"></param>
/// <param name="algorithmname"></param>
public SymmetriclyEncryptedQueryString(string keyfilename, string algorithmname) {
KeyFileName = keyfilename;
AlgorithmName = algorithmname;
}
/// <summary>
/// Use this for decrypte the value.
/// </summary>
/// <param name="encryptedData"></param>
/// <param name="keyfilename"></param>
/// <param name="algorithmname"></param>
public SymmetriclyEncryptedQueryString(string encryptedData, string keyfilename, string algorithmname) {
#region _initials
KeyFileName = keyfilename;
AlgorithmName = algorithmname;
if (String.IsNullOrEmpty(AlgorithmName)){
SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
}
else{
SymmetricEncryptionUtility.AlgorithmName = "DES";
}
SymmetricEncryptionUtility.ProtectKey = false;
// Check for encryption key
if (!File.Exists(KeyFileName)){
throw new FileNotFoundException("Keyfilename for SymmetriclyEncryptedQueryString is not found on '" + KeyFileName + "'!");
}
#endregion
//Arrange the data
//In order not to get following exception
//Invalid length for a Base-64 char array.
//byte[] RawData = Convert.FromBase64String(encryptedData);
encryptedData = encryptedData.Replace(" ", "+");
int mod4 = encryptedData.Length % 4;
if (mod4 > 0)
encryptedData += new string('=', 4 - mod4);
// Decrypt data passed in
byte[] RawData = Convert.FromBase64String(encryptedData);
string DecryptedVal = SymmetricEncryptionUtility.DecryptData(RawData, KeyFileName);
string StringData = DecryptedVal;
// Split the data and add the contents
int Index;
string[] SplittedData = StringData.Split(new char[] { '&' });
foreach (string SingleData in SplittedData) {
Index = SingleData.IndexOf('=');
base.Add(
HttpUtility.UrlDecode(SingleData.Substring(0, Index)),
HttpUtility.UrlDecode(SingleData.Substring(Index + 1))
);
}
}
public override string ToString() {
#region _initials
if (String.IsNullOrEmpty(AlgorithmName)) {
SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
} else {
SymmetricEncryptionUtility.AlgorithmName = "DES";
}
SymmetricEncryptionUtility.ProtectKey = false;
// Check for encryption key
if (!File.Exists(KeyFileName)) {
throw new FileNotFoundException("Keyfilename for AsymmetriclyEncryptedQueryString is not found on '" + KeyFileName + "'!");
}
#endregion
#region _prepare for querystring
// Go through the contents and build a
// typical query string
StringBuilder Content = new StringBuilder();
foreach (string key in base.Keys) {
Content.Append(HttpUtility.UrlEncode(key));
Content.Append("=");
Content.Append(HttpUtility.UrlEncode(base[key]));
Content.Append("&");
}
// Remove the last '&'
Content.Remove(Content.Length - 1, 1);
#endregion
#region _encrypt the contents
// Now encrypt the contents
byte[] data = SymmetricEncryptionUtility.EncryptData(Content.ToString(), KeyFileName);
string EncryptedVal = Convert.ToBase64String(data);
#endregion
return EncryptedVal;
}
}
SymmetricEncryptionUtility
班级
public static class SymmetricEncryptionUtility {
private static bool _ProtectKey;
private static string _AlgorithmName;
// Shhh!!! Don't tell anybody!
private const string MyKey = "m$%&kljasldk$%/65asjdl";
public static string AlgorithmName {
get { return _AlgorithmName; }
set { _AlgorithmName = value; }
}
public static bool ProtectKey {
get { return _ProtectKey; }
set { _ProtectKey = value; }
}
public static void GenerateKey(string targetFile) {
// Create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.GenerateKey();
// No get the key
byte[] Key = Algorithm.Key;
if (ProtectKey)
{
// Use DPAPI to encrypt key
Key = ProtectedData.Protect(
Key, null, DataProtectionScope.LocalMachine);
}
// Store the key in a file called key.config
using (FileStream fs = new FileStream(targetFile, FileMode.Create))
{
fs.Write(Key, 0, Key.Length);
}
}
public static void ReadKey(SymmetricAlgorithm algorithm, string keyFile)
{
byte[] Key;
using (FileStream fs = new FileStream(keyFile, FileMode.Open))
{
Key = new byte[fs.Length];
fs.Read(Key, 0, (int)fs.Length);
}
if (ProtectKey)
algorithm.Key = ProtectedData.Unprotect(Key, null, DataProtectionScope.LocalMachine);
else
algorithm.Key = Key;
}
public static byte[] EncryptData(string data, string keyFile)
{
// Convert string data to byte array
byte[] ClearData = Encoding.UTF8.GetBytes(data);
// Now Create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Encrypt information
MemoryStream Target = new MemoryStream();
// Append IV
Algorithm.GenerateIV();
Target.Write(Algorithm.IV, 0, Algorithm.IV.Length);
// Encrypt actual data
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(ClearData, 0, ClearData.Length);
cs.FlushFinalBlock();
// Output the bytes of the encrypted array to the textbox
return Target.ToArray();
}
public static string DecryptData(byte[] data, string keyFile) {
// Now create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Decrypt information
MemoryStream Target = new MemoryStream();
// Read IV
int ReadPos = 0;
byte[] IV = new byte[Algorithm.IV.Length];
Array.Copy(data, IV, IV.Length);
Algorithm.IV = IV;
ReadPos += Algorithm.IV.Length;
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(data, ReadPos, data.Length - ReadPos);
cs.FlushFinalBlock();
// Get the bytes from the memory stream and convert them to text
return Encoding.UTF8.GetString(Target.ToArray());
}
}
更新 我想出了别的东西。在我的一个页面上,我正在做以下事情;
protected override void OnInit(EventArgs e) {
string url = Request.Url.AbsoluteUri.ToLower();
if (url.StartsWith("http:"))
{
Response.Redirect(url.Replace("http://", "https://"), true);
}
}
我认为它会导致问题。(请记住,我的加密数据位于查询字符串中)当我尝试访问该页面时http
,它会将其重定向到https
并繁荣。它给了我那个错误。好的,现在我找到了错误的根源,但无论如何都不应该发生。