.net – 解密字符串时偶尔出现错误数据错误:System.Security.Cr
在我的ASP.NET WebForms应用程序中(该应用程序在
Windows Server 2008 R2,IIS 7.5和运行时v4.0集成模式应用程序池上运行,如果它很重要),我正在加密数据,将其放在QueryString上并使用System解密数据. Security.Cryptography.SymmetricAlgorithm类.但我偶尔遇到一些解密数据的问题,我得到以下异常;
正如我所指出的那样,我偶尔会遇到这个错误,而不是每次都运行它.我不知道我在哪里做错了(在加密阶段或解密阶段)这是我用于此的代码; 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,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,(int)fs.Length); } if (ProtectKey) algorithm.Key = ProtectedData.Unprotect(Key,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,Algorithm.IV.Length); // Encrypt actual data CryptoStream cs = new CryptoStream(Target,Algorithm.CreateEncryptor(),CryptoStreamMode.Write); cs.Write(ClearData,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()); } } UPDATE 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和繁荣.它给了我那个错误.好吧,我现在找到了错误的来源,但不管怎么说都不应该发生. 解决方法
您的代码中隐藏着一个错误…
永远不要将任何System.Text.Encoding类用于密文.您将遇到间歇性错误.您应该使用Base64编码和System.Convert类方法. >要从加密的byte []获取加密字符串,您应该使用:Convert.ToBase64String(byte [] bytes) 有关其他信息,请参阅MS Security大师Shawn Farkas在http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx的帖子 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 我今天应该使用什么DOCTYPE?
- asp.net-core – 在VS2017中为.NET CORE 2.0设置dotnet-wat
- asp.net-mvc – 在HTML表单上的ASP.NET MVC中的PUT或DELETE
- 在ASP.NET或ASP.NET MVC中生成管理界面
- .net – 什么可以解释托管堆上超过5,000,000个System.WeakR
- asp.net-mvc – ASP.NET MVC从c#代码创建绝对url
- asp.net – 为什么有#!在我的角度应用程序的网址中
- asp.net-mvc – MVC3 – 由几个控制器使用的Helper方法
- Asp.Net Zero轻量级审核流设计
- asp.net – 命名空间“系统”中不存在类型或命名空间名称“