Link to home
Start Free TrialLog in
Avatar of Aleks
AleksFlag for United States of America

asked on

Encrypt querystring

We are developing a NetCore application.  It uses query strings in several places to pass IDs.
What is the best way to hide the querystrings on the browser. I know there is some way of encrypting the whole URL so the parameters are not visible. Can this be done with an IIS setting or third party software?
Avatar of Shaun Vermaak
Shaun Vermaak
Flag of Australia image

Can't you pass as headers? Can you add an encrypt/decrypt function?
You HTTPS + the all data is encrypted over the wire.

To hide the Query String. You can't. The Query String is either there or not.

There can be no hiding of Query Strings, only encrypting so one one can read them off the wire.
Avatar of Aleks

ASKER

I once saw someone encrypting the url on the browser.
I once saw someone encrypting the url on the browser.
Won't be encrypted anywhere else if it was only done client side
Avatar of Aleks

ASKER

We use https. I am not worried about that.
We just don't want the parameters showing on the URL
We use https. I am not worried about that.
Still visible in web server, proxy and any analytic logs
Anything everything that is sent in a browser request including POST requests is visible by some method.  POST data does not show in the URL but you can't make a link that is a POST request.

Consider using encrypted data in cookies as Identification.  Cookies are returned to the server with every request.
Anything everything that is sent in a browser request including POST requests is visible by some method.  POST data does not show in the URL but you can't make a link that is a POST request.

Consider using encrypted data in cookies as Identification.  Cookies are returned to the server with every request.
Yes, as part of the HTTP header as per my first comment
Avatar of noci
noci

The best  & only way to hide query strings, is by not using them.
If POST request bother you, then cookies (or other headerfields) can be useful.
You could encrypt the values that you have in your querystring. But you'd need to take care to encrypt them every time you send that data back from a particular page, and you certainly wouldn't want anything client-side doing the encryption.
Avatar of Aleks

ASKER

I guess the best option is to use post instead of a querystring. I see some net applications that never show anything on the URL. I don't know how the accomplish that, but it is what we were hoping to do as well.
Post some code and we'll be able to help you :)
You asked, "I don't know how the accomplish that, but it is what we were hoping to do as well."

Read carefully through Shaun's + noci's comments.

You'll convert your query string to a cookie + then pass the cookie through Apache headers as part of your session management.
You can encrypt and decrypt the query string. This is extremely handy if you are passing query strings between pages using redirects etc.. This sample does use a redirect if the Request["querystring"] field is empty. If it is empty it encrypts the word case1 and passes it back to this page via a redirect.

If passing query strings between pages as in this example always check your input as this example does. These fields will be human editable etc.. I use switch to process the incoming query strings in this example.

exptest.aspx
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography" %> 

<%
//exptest.aspx


String decryptstr = "";

 if(!string.IsNullOrEmpty(Request["querystring"])){
if(!CharCheck(Request["querystring"])){decryptstr = "";}
else{decryptstr = Decrypt(Request["querystring"], true, "cypherkey");}
}

switch (decryptstr){
case "case1":%>
Case1 reply
<% break;
case "case2":%>
Case2 reply
<% break;
}


if(string.IsNullOrEmpty(Request["querystring"])){
Response.Redirect("exptest.aspx?querystring=" + Encrypt("case1", true, "cypherkey"));
}

%>
<script runat="server">


   bool CharCheck(string fieldt)
   {
       if((fieldt == "") || (fieldt == null)){return false;}
       String pattern =  @"^([a-zA-Z0-9-\-=]+)$";
       Regex check = new Regex(pattern);
       if (check.IsMatch(fieldt, 0) == true) { return true; }
       else { return false; }
   }

   public static string Encrypt(string toEncrypt, bool useHashing, string passkey)
   {
       byte[] keyArray;
       byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
       string key = passkey;
       if (useHashing)
       {
           MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
           keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
           hashmd5.Clear();
       }
       else 
           keyArray = UTF8Encoding.UTF8.GetBytes(key);
           TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
           tdes.Key = keyArray;
           tdes.Mode = CipherMode.ECB;
           tdes.Padding = PaddingMode.PKCS7;
          ICryptoTransform cTransform = tdes.CreateEncryptor();
          byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0,
          toEncryptArray.Length);
          tdes.Clear();
       return Convert.ToBase64String(resultArray, 0, resultArray.Length);
   }

   
   public static string Decrypt(string cipherString, bool useHashing, string passkey)
   {
       byte[] keyArray;
       byte[] toEncryptArray = Convert.FromBase64String(cipherString);
       string key = passkey;
       if (useHashing)
       {
           MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
           keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
           hashmd5.Clear();
       }
       else
       {
           keyArray = UTF8Encoding.UTF8.GetBytes(key);
       }

       TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
       tdes.Key = keyArray;
       tdes.Mode = CipherMode.ECB;
       tdes.Padding = PaddingMode.PKCS7;
       ICryptoTransform cTransform = tdes.CreateDecryptor();
       byte[] resultArray = cTransform.TransformFinalBlock(
                            toEncryptArray, 0, toEncryptArray.Length);
         tdes.Clear();
       return UTF8Encoding.UTF8.GetString(resultArray);
   }

</script>

Open in new window

You can POST to the server. From the link call a JavaScript JQuery function that would trigger a POST back to the server via AJAX and then on onSuccess of the AJAX function you can resume processing.
Avatar of Aleks

ASKER

I am not sure which method was use, but the developers I have were able to find a way to encrypt the URL.
Keep in mind, you should always be using HTTPS + if you are using HTTPS, there's no encryption you can add which will provide better encryption than HTTPS.

Best to use HTTPS + keep your query strings simple.
ASKER CERTIFIED SOLUTION
Avatar of Aleks
Aleks
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you're using HTTPS, then your query string is already encrypted to anyone not making the request.

For people making the request, they can still see the query string + use the query string, independent of any encryption.

So HTTPS is all that's required.