Password hash using PBKDF2 with HMAC SHA256/ SHA512 in .NET Framework 4.7.2 and .NET Core 2.0

Here I am back with more updates on PBKDF2 with HMAC but this time I am talking about SHA-2 family of hashes which includes SHA-256 and SHA-512, both that to in standard .NET framework.

I have posted another article for implementing PBKDF2 with SHA-2 family for password hashing which has custom implementation of PBKDF2 as at that time this option was not available in standard .NET framework. Keep on reading

Browser back button triggers previous post action in .NET webform application – solved

Recently while working on one of my .NET application I was stuck in a strange problem. I created a button and its click event to insert some entry in database and at the end of this action I used below statement to redirect the page for next step.

Response.Write("<script>top.location="next step page url";</script>");

=&0=& I used this method to redirect the page because I was doing it in an iframe and wanted to redirect parent page after this step is completed and next step is started.

This was working perfectly fine but after moving to next step when I clicked browser back button same action was again fired and I got two similar entries in database. This was strange because I never exacted post event to be actually fired on browser back button because browser used to show a message when there is any post action is required (like we tap browser refresh button after any post action).

After some hit and trial I found that the statement above (Response.Write) is causing the issue. This was because the post action was still in progress because I used a trick to redirect instead of simple Response.Redirect.

To complete the post event and redirect properly to resolve the page postback issue on browser back button I used below approach in place of above like of statement:

Session["next"] = true
Response.Write("<script>top.location=top.location;</script>");

On parent page I checked if this session exists then redirect to next step

if(Session["next"] != null && Convert.ToBoolean(Session["next"]))
{
     Response.Redirect("next step page url");
}

After this approach when I clicked browser back button there was not issue of postback.

So the conclusion was that Response.Write was actual reason of the issue because it was breaking the flow without completing the post action.

Visual studio 2017 will be launched on 7th March 2017

Finally Microsoft is going to launch Visual studio 15 (Visual studio 2017) on 7th March.

This version of Visual Studio will be launched at an event which will be organised on 7th and 8th March. This will also be a celebration event for 20th Anniversary of Visual Studio.

=&0=& of the event will include Keynote and demos by Julia Liuson, Brian Harry, Miguel de Icaza, and Scott Hanselman which can also be viewed on live streaming. They will show new things in Visual Studio, .NET, Xamarin, Azure etc.

Day 2 (8th March 2017) will be live interactive training day to teach how to be more productive using the all new Visual Studio 2017.

If you are interested in this event then you can register on this link https://launch.visualstudio.com

Apart from this live event there will be launch event by the Visual Studio community all around the world where developers can meet and collaborate in their local area.

You can even share a short story, video clip or image of your visual studio story. Share your story on Instagram, Twiter or Facebook with #MyVSStory

Encryption and Decryption of content using RijndaelManaged Class in C#

If you want to encrypt and decrypt data in your .NET application then one of the most simplest and safest way is using RijndaelManaged class.

It is predecessor of Aes but still most of the new users us RijndaelManaged class because it is easy to plug and use.

First we have to generate an encryption key using a password ans salt. Password and salt could be any string (use base64 string to make your encryption stronger) which we have to convert to bytes array (byte[]) before using them for generating encryption key. Below is the complete example of generating key and encryption and decryption

public static byte[] GenerateEncryptionKey(string password, string saltString)
{
	byte[] salt = Convert.FromBase64String(saltString);
	var keyGen = new Rfc2898DeriveBytes(password, salt, 7845);
	return keyGen.GetBytes(32);
}
public static string Encrypt(object data, string password, string saltString)
{
	try
	{
		using (var aes = new RijndaelManaged())
		{
			//get some bytes
			aes.Key = GenerateEncryptionKey(password, saltString);
			aes.BlockSize = 256;
			aes.Padding = PaddingMode.PKCS7;

			//generate an IV
			aes.GenerateIV();

			//get the bytes for our message
			var plainBytes = Encoding.UTF8.GetBytes(data.ToString());

			//start up the encryption
			using (var ms = new MemoryStream())
			using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
			{
				//write the bytes to the cryptostream
				cs.Write(plainBytes, 0, plainBytes.Length);
				cs.FlushFinalBlock();

				//get message bytes
				var msgBytes = ms.ToArray();

				//create a new array big enough for the both of 'em
				var cypherBytes = new byte[aes.IV.Length + msgBytes.Length];

				//return the string with the iv as the first 32 bytes. will need this when decrypting
				System.Buffer.BlockCopy(aes.IV, 0, cypherBytes, 0, aes.IV.Length);
				System.Buffer.BlockCopy(msgBytes, 0, cypherBytes, aes.IV.Length, msgBytes.Length);

				//now convert it to base64 string
				var cypherText = System.Convert.ToBase64String(cypherBytes).TrimEnd(new char[] { '=' }).Replace('+', '-').Replace('/', '_');
				//var cypherText = Convert.ToBase64String(cypherBytes);

				//return cypher text
				return cypherText;
			}
		}
	}
	catch (Exception)
	{
		return null;
	}
}

public static string Decrypt(object cypherData, string password, string saltString)
{
	try
	{
		using (var aes = new RijndaelManaged())
		{
			//get some bytes
			aes.Key = GenerateEncryptionKey(password, saltString);
			aes.BlockSize = 256;
			aes.Padding = PaddingMode.PKCS7;

			//get the bytes for our message
			string cypherStr = cypherData.ToString();
			string incoming = cypherStr.Replace('_', '/').Replace('-', '+');
			switch (cypherStr.Length % 4)
			{
				case 2: incoming += "=="; break;
				case 3: incoming += "="; break;
			}
			
			var cypherBytes = Convert.FromBase64String(incoming);
			//var cypherBytes = Convert.FromBase64String(cypherData.ToString());
			var iv = new byte[aes.IV.Length];
			var msgBytes = new byte[cypherBytes.Length - iv.Length];

			//we use the first 32 bytes of the cypherdata for the IV
			System.Buffer.BlockCopy(cypherBytes, 0, iv, 0, iv.Length);
			System.Buffer.BlockCopy(cypherBytes, iv.Length, msgBytes, 0, msgBytes.Length);

			//set the IV for the instance
			aes.IV = iv;

			//start up the decryption
			using (var ms = new MemoryStream())
			using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
			{
				//write the bytes to the cryptostream
				cs.Write(msgBytes, 0, msgBytes.Length);
				cs.FlushFinalBlock();
					  
				//the plain text has been decrypted.
				var plainText = System.Text.Encoding.UTF8.GetString(ms.ToArray());

				//return plain text
				return plainText;
			}
		 }
	}
	catch (Exception)
	{
		return null;
	}
}

Send FCM data message & notification to Android, iOS & Web in C#

In my previous article I have explained about types of notification messages in FCM. We have already learnt how to send GCM notification using C#. Now because FCM is replacing GCM so here we are with new sample of working with FCM in C#.

public class NotificationManager
{
	private class NotificationMessage
	{
		public string Title;
		public string Message;
		public long ItemId;
	}
    
	public NotificationManager()
	{
		//
		// TODO: Add constructor logic here
		//
	}

	public string SendNotification(List deviceRegIds, string message, string title, long id)
	{
		string SERVER_API_KEY = "";
		var SENDER_ID = "";
		string regIds = string.Join("","", deviceRegIds);
		
		NotificationMessage nm = new NotificationMessage();
		nm.Title = title;
		nm.Message = message;
		nm.ItemId = id;

		var value = new JavaScriptSerializer().Serialize(nm);

		WebRequest tRequest;
		tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
		tRequest.Method = "post";
		tRequest.ContentType = "application/json";
		tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

		tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

		string postData = "{"collapse_key":"score_update","time_to_live":108,"delay_while_idle":true,"data": { "message" : " + value + ","time": " + """ + System.DateTime.Now.ToString() + ""},"registration_ids":["" + regIds + ""]}";

		Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
		tRequest.ContentLength = byteArray.Length;

		Stream dataStream = tRequest.GetRequestStream();
		dataStream.Write(byteArray, 0, byteArray.Length);
		dataStream.Close();

		WebResponse tResponse = tRequest.GetResponse();

		dataStream = tResponse.GetResponseStream();

		StreamReader tReader = new StreamReader(dataStream);

		String sResponseFromServer = tReader.ReadToEnd();

		tReader.Close();
		dataStream.Close();
		tResponse.Close();
		return sResponseFromServer;
	}
}

You can see that only difference between GCM and FCM code is the request url where we have to post our data and yes this is the only difference between GCM and FCM except another notification message.

Above code is data notification message which is also called payload message. FCM provide simple notification message also which we don’t need to handle in our code in client app or we can say we can not handle because FCM will automatically catches it display on our app’s behalf. Upon clicking on this message it will open your app.

To send this kind of notification we simply need to replace data part of our message json (see string variable postData) with new notification json which should be like below:

{
	"to" : "yourclientregistrationid...",
	"notification" : {
		"body" : "notification body",
		"title" : "notification title",
		"icon" : "displayicon"
	}
}

Transferring Cookies from WebBrowser to WebClient

I have prepared many web scrapping application and crawlers. Few of them were developed using WebClient and others were with WebBrowser control of .NET (see my previous article to Get and Set Cookies .NET WebBrowser Control). Recently I got stuck in a situation where I need features of both tools. That is WebClient and WebBrowser.

So my idea was to use WebBrowser control and pass on the session to WebClient when WebClient features are required.

For this my first task was to make WebClient aware of cookies and behave accordingly. SO After searching for few minutes I got this SO link which gave me a class to make cookie aware WebClient and after modifying it I got this final class CookieAwareWebClient

public class CookieAwareWebClient : WebClient
{
	public CookieContainer CookieContainer { get; set; }
	public Uri Uri { get; set; }
	
	public CookieAwareWebClient() : this(new CookieContainer())
	{
	
	}

	public CookieAwareWebClient(CookieContainer cookies)
	{
		this.CookieContainer = cookies;
	}

	protected override WebRequest GetWebRequest(Uri address)
	{
		WebRequest request = base.GetWebRequest(address);
		if (request is HttpWebRequest)
		{
			(request as HttpWebRequest).CookieContainer = this.CookieContainer;
		}
		
		HttpWebRequest httpRequest = (HttpWebRequest)request;
		httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
		return httpRequest;
	}

	protected override WebResponse GetWebResponse(WebRequest request)
	{
		WebResponse response = base.GetWebResponse(request);
		String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];

		if (setCookieHeader != null)
		{
			//do something if needed to parse out the cookie.
			if (setCookieHeader != null)
			{
				Cookie cookie = new Cookie(); //create cookie
				this.CookieContainer.Add(cookie);
			}
		}
		return response;
	}
}

Now I have to use this class in place of WebClient because it supports cookies for by browsing.

Next thing that I have to do is pass all the cookies from my WebBrowser to this cookie aware web client. Here is how I did this:

CookieContainer cookieJar = new CookieContainer();
string[] cookies = browser.Document.Cookie.Split(new char[] { '=' });
cookieJar.Add(new Cookie(cookies[0], cookies[1], "/", "edunyte.com"));

In above code browser is my WebBrowser control object and because I have only one cookie value associated with it so I parsed (cookie key and value) it and assigned it to my cookie container. If you have multiple cookies then parse each of them and associate with cookie container.

Now because all cookies which were associated with WebBrowser browsing session is not assigned to my Cookie container so I can create CookieAwareWebClient object using this cookie container.

CookieAwareWebClient client = new CookieAwareWebClient(cookieJar);

Now we are ready with our cookie aware client with required cookies assigned to it so we can start sending request using this object and it will behave like it is cookie owner.

Get and Set Cookies .NET WebBrowser Control

I faced this situation many times where I have to transfer cookies from one WebBrowser control to other so that I can transfer the authentication and after searching I found a simple and straight forward solution for doing this.

Get Cookies from WebBrowser Control

After doing your operation like navigating to any page and login on the site you just have to write this code in any event:

string cookies = browser.Document.Cookies;

Above line of code will return a string containing all cookies in cookies string.

Now you can use this string to set cookies of other webbrowser control. But keep in mind that cookies string is found in Document property of WebBrowser control and document is only initialised after navigating to some URL. So before assigning these cookies either navigate to that domain who generated these cookies or set cookies while navigating.

Set Cookies in WebBrowser Control

There are two methods to set cookies in web browser control

1. This is very straight forward method to assign cookies in Cookie property of your WebBrowser’s document object:

wb.Document.Cookie = cookies;

This method may not work for all sites specially on sites running on https protocol.

2. As above method doesn’t guarantee to run on all sites so here is second method which you can use to set cookies:

=&2=&

[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool InternetSetCookie(string lpszUrlName, string lpszCookieName, string lpszCookieData);

=&3=& =&4=&

Cookie ck = new Cookie("key", "value", "/folder", "/");
InternetSetCookie("https://edunyte.com/folder", null, ck.ToString());

Now you can navigate to the URL specified in InternetSetCookie to read the cookie and verify that it is working.

Send message to GCM in C#.NET for single or multiple device delivery

In previous articles we learnt about how google cloud messaging works and how to register android device on GCM for getting registration id.

Note: This post only explains how you can send same message to single or multiple devices but there is know method provided by GCM to send different message to different devices in one request.

Now we will see how we can send request to GCM server for sending notification to mobile devices. In this example we will use .NET as our server platform and C# as programming language.

For making code usable for single as well as multiple registration ids we have used list and converted it to comma separated strings. This comma separated string can be passed in our request and GCM server will relay our message to corresponding devices.

Below is the sample code:

public class NotificationManager
    {
        private class NotificationMessage
        {
            public string Title;
            public string Message;
            public long ItemId;
        }

         public NotificationManager()
        {
            //
            // TODO: Add constructor logic here
            //
        }

         public string SendNotification(List<string> deviceRegIds, string message, string title, long id)
        {
string SERVER_API_KEY = ;
var SENDER_ID = ;
string regIds = string.Join("","", deviceRegIds);

NotificationMessage nm = new NotificationMessage();
nm.Title = title;
nm.Message = message;
nm.ItemId = id;

var value = new JavaScriptSerializer().Serialize(nm);

WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

string postData = "{"collapse_key":"score_update","time_to_live":108,"delay_while_idle":true,"data": { "message" : " + value + ","time": " + """ + System.DateTime.Now.ToString() + ""},"registration_ids":["" + regIds + ""]}";

Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;

Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse tResponse = tRequest.GetResponse();

dataStream = tResponse.GetResponseStream();

StreamReader tReader = new StreamReader(dataStream);

String sResponseFromServer = tReader.ReadToEnd();

tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
    }

In above example we have creates class named NotificationMessage for message format. We will convert object of this class to json and sent it as message.

In SendNotification method of the class, just pass list of registration ids along with message title, body and message id which we will use to show message on mobile device.

To use this code you have to create account on google developer console and generate credentials. Follow this article if you want to learn how to create account and generate credentials for GCM.

Get HtmlDocument from string in C#

Hi,

In this article I want to share how we can convert a string containing HTML content to HtmlDocument (System.Windows.Forms.HtmlDocument).

Some of you might thing why I want to do that but the answer is simply my need, actually HtmlDocument class profiles many methods to manipulate HTML content in any string. For example it gives various javascript like operations to reach and operate on HTML elements.

I searched for it many times but didn’t find any single place where I get exact solution, so after some hit and tries and combining solutions given n various Stackoverflow questions I come up with this simple code block.

        public System.Windows.Forms.HtmlDocument GetHtmlDocument(string html)
        {
            WebBrowser browser = new WebBrowser();
            browser.ScriptErrorsSuppressed = true; //not necessesory you can remove it
            browser.DocumentText = html;
            browser.Document.OpenNew(true);
            browser.Document.Write(html);
            browser.Refresh();
            return browser.Document;
        }

I used to set ScriptErrorsSuppressed to true ever time I use WebBrowser control because this get me out of any script error or warning.