Friday, June 9, 2017

C# MVC Query String Encoding and Decoding

Leave a Comment

I want to encode and decode the url parameters.

calling function in javascript

var url = '/Demo/Demo?id=58'; $(location).attr('href', url) 

Current url parameter

www.example.com/Demo/Demo?id=58

code in Demo controller

public ActionResult Demo(int id) {    return view(); } 

i want the above url to be changed like the bolow line

www.example.com/Demo/Demo?id=Sff5f8ddg

So that the id value will be confidential. what is the best way to encode and decode.

Note: we calling method by anchor tag, ajax and jquery. Encoding and Decoding other than Base64

Is there any cryptography method other than Base64 enoding and decoding like encrypt in javascript and decrypt in C# method

9 Answers

Answers 1

So that the id value will be confidential. what is the best way to encode and decode.

It won't. At least in the way you are trying to make it. As soon as you encode the [internal] id it becomes the public id for that entry. It does not matter for user which id to use: 58 or Sff5f8ddg, as it would refer to the same entry in the system. If you are using unsalted algorithms it would prevent only not so sophisticated users to discover other entries in your system.

As I understand the problem you are trying to solve is - how to make other entries undiscoverable by having an id for some entry(ies). Eg, if user has an url for entry 58, they should not be able to find entries 57 and 59.

The solution is: use GUIDs as ID for your entries.

Also, you need to make sure that you've implemented proper access control for your entries.

Answers 2

var id=Encrypt(YourID); var id=Decrypt(YourID);    using System.Security.Cryptography;  public static string Encrypt(string inputText)     {         string encryptionkey = "SAUW193BX628TD57";         byte[] keybytes = Encoding.ASCII.GetBytes(encryptionkey.Length.ToString());         RijndaelManaged rijndaelCipher = new RijndaelManaged();         byte[] plainText = Encoding.Unicode.GetBytes(inputText);         PasswordDeriveBytes pwdbytes = new PasswordDeriveBytes(encryptionkey, keybytes);         using (ICryptoTransform encryptrans = rijndaelCipher.CreateEncryptor(pwdbytes.GetBytes(32), pwdbytes.GetBytes(16)))         {             using (MemoryStream mstrm = new MemoryStream())             {                 using (CryptoStream cryptstm = new CryptoStream(mstrm, encryptrans, CryptoStreamMode.Write))                 {                 cryptstm.Write(plainText, 0, plainText.Length);                 cryptstm.Close();                 return Convert.ToBase64String(mstrm.ToArray());                 }             }         }     }  public static string Decrypt(string encryptText) {     string encryptionkey = "SAUW193BX628TD57";     byte[] keybytes = Encoding.ASCII.GetBytes(encryptionkey.Length.ToString());     RijndaelManaged rijndaelCipher = new RijndaelManaged();     byte[] encryptedData = Convert.FromBase64String(encryptText.Replace(" ", "+"));     PasswordDeriveBytes pwdbytes = new PasswordDeriveBytes(encryptionkey, keybytes);     using (ICryptoTransform decryptrans = rijndaelCipher.CreateDecryptor(pwdbytes.GetBytes(32), pwdbytes.GetBytes(16)))     {         using (MemoryStream mstrm = new MemoryStream(encryptedData))         {             using (CryptoStream cryptstm = new CryptoStream(mstrm, decryptrans, CryptoStreamMode.Read))             {             byte[] plainText = new byte[encryptedData.Length];             int decryptedCount = cryptstm.Read(plainText, 0, plainText.Length);             return Encoding.Unicode.GetString(plainText, 0, decryptedCount);             }         }     } } 

Answers 3

In javascript, you can use

var str = "Hello World!"; var enc = window.btoa(str); var dec = window.atob(enc); 

The result of res will be:

Encoded String: SGVsbG8gV29ybGQh Decoded String: Hello World! 

This example shows you how to use the RijndaelManaged for encryption decryption.

 public static class Cryptography     {          private static readonly byte[] _key = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03 };         private static readonly byte[] _iV = { 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13, 0x10, 0x11, 0x12, 0x13 };          #region Encryption           public static string Encrypt(this string inputText)         {             string _encryptString = string.Empty;             if (string.IsNullOrEmpty(inputText))                 return string.Empty;             else             {                 ASCIIEncoding textConverter = new ASCIIEncoding();                 RijndaelManaged myRijndael = new RijndaelManaged();                  ICryptoTransform encryptor = myRijndael.CreateEncryptor(_key, _iV);                 MemoryStream msEncrypt = new MemoryStream();                 CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);                 byte[] toEncrypt = textConverter.GetBytes(inputText);                 csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);                 csEncrypt.FlushFinalBlock();                 _encryptString = Convert.ToBase64String(msEncrypt.ToArray()).Replace(" ", "+");                 return _encryptString;             }         }          public static string Decrypt(this string inputText)         {             string text = inputText;             try             {                 if (string.IsNullOrEmpty(inputText))                     return string.Empty;                 else                 {                     inputText = inputText.Replace(" ", "+");                      byte[] encrypted = Convert.FromBase64String(inputText);                     ASCIIEncoding textConverter = new ASCIIEncoding();                     RijndaelManaged myRijndael = new RijndaelManaged();                      ICryptoTransform decryptor = myRijndael.CreateDecryptor(_key, _iV);                     MemoryStream msDecrypt = new MemoryStream(encrypted);                     CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);                     byte[] fromEncrypt = new byte[encrypted.Length];                     csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);                     return textConverter.GetString(fromEncrypt).TrimEnd('\x0');                 }             }             catch (FormatException)             {                 return "";             }             catch (Exception ex)             {                 return text;             }         }            #endregion Encryption      } 

Now encrypt decrypt in controller Like

 "id".Encrypt();///   "encryptID".Decrypt(); 

Answers 4

What I am able to understand from your question is that you want to restrict user from being able to know the exact value of the id parameter.

But that's not gonna help because you already have that value on your browser/client side. so you have id on your client and you want to restrict your client from knowing its value. An average developer(anyone who write code) can access your value using developer tool of browser. So no benefit.

Another way is you send your id encrypted from server itself. For that you can use the solution provided by @Karan Singh. Or any other option you want to explore for that matter is up to you.

One suggestion try to use an encryption method which can not be done in reverse. This will add overhead in processing as you will have to first encrypt your Id from DB and then match it with the value sent by client.

Thanks.

Answers 5

You can simply use jquery function like:

var encodedUrl = encodeURIComponent("your url"); //'/Demo/Demo?id=58'; console.log(encodedUrl);

Thank you

Answers 6

If what you are looking to do is to hide the 58 from the rendered content (client-side), then you need to implement an encryption/decryption scheme on the backend and pass that value from/to the client side as needed.

When you provide data to the client, your server side code will encrypt the 58 into some string in order to conceal the real value and pass that to the client.

When the client issues a request to you, it should use that encrypted string that you provided before and your server should decrypt it into something it can use.

You don't need JavaScript to encrypt and C# to decrypt the values. The JavaScript portion should be working off of the encrypted id at all times since it's scripting that is executing after the fact at the client side. How the value is consumed on the server side is an internal aspect of which the client-side JavaScript does not need to know about.

Answers 7

You want to encode / decode parameters, but the question is why? What are you trying to accomplish in the first place? What is your requirement and how sensitive is the data on the page? What is the purpose of the id, does it identify a user or a page?

If you are thinking of sharing a link or publish it (anchor tag) on an unsecured page, then consider the fact that the link can be shared beyond control or even stolen. Anyone who has the link can access the page. How are you going to detect that it is compromised? How are you going to revoke the link?

It doesn't even matter then how you encrypt the id: a random string, a highly encrypted id, a GUID (which isn't safe either since an attacker will recognize that it's a GUID and can use brute force attack to 'guess' available guid's).

The best chance you may have is to use an auto-expiring link which has some random value and variable length id (so it cannot be guessed). Store the value in the database with expiration date and link to the actual id. This doens't prevent the link from being shared, but at least you can limit possible damage.

But: the only way to prevent unauthorized access is to add a level of security. You can try to think of all kinds of things to secure your data, but in the end you are re-inventing security. Why don't you take a look at modern security, like OpenId Connect and OAuth2. If you want to secure your resource, implement something like Asp.Net Identity 2.

Answers 8

Hello anand i think you want to create a temper proof Query string Download the code from github repository

Answers 9

controller:

[HttpPost]         public ActionResult SubmitInputTest(int id) {              //your code              //do stuff              return RedirectToAction("index");         } 

In your view (cshtml):

<form id="frmToSubmit" action="<controller>/SubmitInputTest">  <hidden id="id" name="id"/> </form> 

In your javascript:

$('#id').attr('value', [your ID Value]); $('#frmToSubmit').submit(); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment