Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Wednesday, September 13, 2017 7:42 PM
For my MVC website I want to send an encrypted parameter (token) value in the URL to the Controller and the Controller will decrypt the value. This is for sensitive data in a public faccing website. How do I encrypt the parameter value in my razor page and how to decrypt in the Controller?
Thanks.
All replies (2)
Thursday, September 14, 2017 11:40 AM âś…Answered
Hi gunderj,
According to your requirement, I suggest you could create a custom Razor control to pass what parameter values of url you want to encrypt.
And you could define a custom EncryptedActionParameter attribute to decrypt these parameter values.
You could add this attribute to what action method you want to decrypt. Then you could show these decrypt values to view.
Please refer to my code:
Create a Filters folder>add the EncryptedActionParameterAttribute class: (decrypt the parameter values from url)
[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], (paramArr[1]));// pass two string parameters
}
}
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());
}
Code in Models>Create MyExtensions class: (encrypt the parameter values of url )
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;
if (routeValues != null)
{
RouteValueDictionary d = new RouteValueDictionary(routeValues);
for (int i = 0; i < d.Keys.Count; i++)
{
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);
}
}
//What is Entity Framework??
StringBuilder ancor = new StringBuilder();
ancor.Append("<a ");
if (htmlAttributesString != string.Empty)
{
ancor.Append(htmlAttributesString);
}
ancor.Append(" href='");
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("");
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());
}
}
Code in Controller:
public ActionResult Demo1()
{
return View();
}
//http://localhost:54996//Test2/TestEncrypt?a=hh&b=abc original url before encryption
[EncryptedActionParameter]
public ActionResult TestEncrypt(string a, string b)
{
ViewBag.DecryptInfo= "a:" + a + "\tb:" + b; // pass the decrypt parameter values to View
return View();
}
Code in View:
Code in Demo1.cshtml:
using WebMVC6.Models
@{
ViewBag.Title = "Demo1";
}
<h4>Demo1</h4>
@Html.EncodedActionLink("TestEncrypt", "TestEncrypt", "Test2", new { a="hh",b="abc" }, null)@*the original parameter value*@
Code in TestEncrypt.cshtml:
@{
ViewBag.Title = "TestEncrypt";
}
<h4>TestEncrypt</h4>
<label>DecryptInfo:</label>
<p>@ViewBag.DecryptInfo</p>
Finally, you could see the result like this:
Best regards,
Dillion
Thursday, September 14, 2017 1:35 AM
you need to pick an encryption library that meets your security need. start here:
/en-us/dotnet/standard/security/cryptographic-services
sha1 will probably work for you, see this example code:
/en-us/dotnet/api/system.security.cryptography.hmacsha1?view=netframework-4.7
i'd probably encrypt in the controller and pass the encrypted value to the view.