2015-10-14 81 views
1

我正在尝试利用tutorial中的代码,并且我不断收到一些我无法弄清楚如何解决的错误。Url加密问题

下面的行失败执行:

inputByte = Convert.FromBase64String(encryptedText);

它提供这样的错误:

Invalid length for a Base-64 char array or string.

接着,这条线还未能执行。

Dictionary decryptedParameters = new Dictionary();

而返回的错误是:

Index was outside the bounds of the array.

我该如何去修复呢?


类EncryptedActionParameterAttribute:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Threading; 
using System.Web.Mvc; 
using WebMatrix.WebData; 
using Medi.Models; 
using System.Security.Cryptography; 
using System.IO; 

namespace Medi.Filters 
    { 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public class EncryptedActionParameterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

     Dictionary<string, object> decryptedParameters = new Dictionary<string, object>(); 
     if (HttpContext.Current.Request.QueryString.Get("q") != null) 
     { 
      string encryptedQueryString = HttpContext.Current.Request.QueryString.Get("q"); 
      string decrptedString = Decrypt(encryptedQueryString.ToString()); 
      string[] paramsArrs = decrptedString.Split('?'); 

      for (int i = 0; i < paramsArrs.Length; i++) 
      { 
       string[] paramArr = paramsArrs[i].Split('='); 
       decryptedParameters.Add(paramArr[0], Convert.ToInt32(paramArr[1])); 
      } 
     } 
     for (int i = 0; i < decryptedParameters.Count; i++) 
     { 
      filterContext.ActionParameters[decryptedParameters.Keys.ElementAt(i)] = decryptedParameters.Values.ElementAt(i); 
     } 
     base.OnActionExecuting(filterContext); 

    } 

    private string Decrypt(string encryptedText) 
    { 
     string key = "jdsg432387#"; 
     byte[] DecryptKey = { }; 
     byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 }; 
     byte[] inputByte = new byte[encryptedText.Length]; 

     DecryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8)); 
     DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
     inputByte = Convert.FromBase64String(encryptedText); 
     MemoryStream ms = new MemoryStream(); 
     CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(DecryptKey, IV), CryptoStreamMode.Write); 
     cs.Write(inputByte, 0, inputByte.Length); 
     cs.FlushFinalBlock(); 
     System.Text.Encoding encoding = System.Text.Encoding.UTF8; 
     return encoding.GetString(ms.ToArray()); 
    } 
} 
} 

MyExtensions类别:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using System.Text; 
using System.Web.Routing; 
using System.Security.Cryptography; 
using System.IO; 

namespace Medi.Models 
{ 
public static class MyExtensions 
{ 
    public static MvcHtmlString EncodedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) 
    { 
     string queryString = string.Empty; 
     string htmlAttributesString = string.Empty; 
     string AreaName = string.Empty; 
     if (routeValues != null) 
     { 
      RouteValueDictionary d = new RouteValueDictionary(routeValues); 
      for (int i = 0; i < d.Keys.Count; i++) 
      { 
       string elementName = d.Keys.ElementAt(i).ToLower(); 
       if (elementName == "area") 
       { 
        AreaName = Convert.ToString(d.Values.ElementAt(i)); 
        continue; 
       } 
       if (i > 0) 
       { 
        queryString += "?"; 
       } 
       queryString += d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i); 
      } 
     } 

     if (htmlAttributes != null) 
     { 
      RouteValueDictionary d = new RouteValueDictionary(htmlAttributes); 
      for (int i = 0; i < d.Keys.Count; i++) 
      { 
       htmlAttributesString += " " + d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i); 
      } 
     } 

     //<a href="/Answer?questionId=14">What is Entity Framework??</a> 
     StringBuilder ancor = new StringBuilder(); 
     ancor.Append("<a "); 
     if (htmlAttributesString != string.Empty) 
     { 
      ancor.Append(htmlAttributesString); 
     } 
     ancor.Append(" href='"); 
     if (AreaName != string.Empty) 
     { 
      ancor.Append("/" + AreaName); 
     } 
     if (controllerName != string.Empty) 
     { 
      ancor.Append("/" + controllerName); 
     } 

     if (actionName != "Index") 
     { 
      ancor.Append("/" + actionName); 
     } 
     if (queryString != string.Empty) 
     { 
      ancor.Append("?q=" + Encrypt(queryString)); 
     } 
     ancor.Append("'"); 
     ancor.Append(">"); 
     ancor.Append(linkText); 
     ancor.Append("</a>"); 
     return new MvcHtmlString(ancor.ToString()); 
    } 

    private static string Encrypt(string plainText) 
    { 
     string key = "jdsg432387#"; 
     byte[] EncryptKey = { }; 
     byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 }; 
     EncryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8)); 
     DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
     byte[] inputByte = Encoding.UTF8.GetBytes(plainText); 
     MemoryStream mStream = new MemoryStream(); 
     CryptoStream cStream = new CryptoStream(mStream, des.CreateEncryptor(EncryptKey, IV), CryptoStreamMode.Write); 
     cStream.Write(inputByte, 0, inputByte.Length); 
     cStream.FlushFinalBlock(); 
     return Convert.ToBase64String(mStream.ToArray()); 
    } 
} 
} 

回答

1

我怀疑上的Base64无效长度误差引起从一些 '=' 标志被从滴下请求参数。

This answer很好地解释它。

The length of a base64 encoded string is always a multiple of 4. If it is not a multiple of 4, then = characters are appended until it is. A query string of the form ?name=value has problems when the value contains = charaters (some of them will be dropped, I don't recall the exact behavior). You may be able to get away with appending the right number of = characters before doing the base64 decode.

至于你的字典的话,你没有提供的任何类型的参数,编译器不知道你想要什么..

尝试供应类型如下:

Dictionary<string, string> decryptedParameters = new Dictionary<string, string>();