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

AutoMapper configuration in older and newer versions

Recently when I was looking for various architecture approached and tools sets, I saw this post which is very useful. But while I was going through the post I was getting error while implementing AutoMapper. I started getting below errors when I tried to configure AutoMapper as given on the link.

  • The type or namespace name ‘Profile’ could not be found (are you missing a using directive or an assembly reference?)
  • ‘ViewModelToDomainMappingProfile.ProfileName’: no suitable method found to override
  • ‘ViewModelToDomainMappingProfile.Configure()’: no suitable method found to override
  • ‘DomainToViewModelMappingProfile.Configure()’: no suitable method found to override
  • ‘Mapper’ does not contain a definition for ‘CreateMap’
  • ‘Mapper’ does not contain a definition for ‘CreateMap’

After some time I figured out the problem. Actually while following the tutorials I installed latest version (7.0.1 at that time) of AutoMapper from nuget while this tutorial was using 3.3.1 (that article was written sometime in 2015). Keep on reading

Password hash using PBKDF2 with HMAC SHA256/ SHA512 in .NET Framework 4.7 and before

Recently I got an requirement from one of my client to generate salted password hash using PBKDF2 and SHA-2 algorithms. But as everyone knows we only have SHA-1 available in .NET framework till now.

Because this was an client requirement so I have to accommodate in my project scope and to do this I got help from a nice guy who made this easy for me. While doing search on google I found this article from that guy. 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.

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"
	}
}

Deployment Failed: Unexpected Exception – AWS EBS deployment error

Recently I was trying to deploy my .NET project on AWS Elastic Beanstalk (EBS) using AWS Toolkit for Visual Studio.

Before this deployment attempt this same project was published on same EBS where I was just updating the project after making some changes. But unfortunately I was getting an error message (=&0=&) every time I try to deploy the project on my AWS EBS instance and deployment gets failed hence EBS redeployed my previous deployed code again.

I searched for many days but none of the solution helped me resolve my issue and I started inspecting the changes I made between current and previous deployment.

After removing all the change I made in my aspx and cs paged I tried redeployment and it was really frustrating that I got same error (=&0=&) and EBS again reverted my code to previous deployment.

Suddenly one thing strike in my mind that recently I updated AWS SDK in my project and after checked further I noticed that during updation process I mistakenly added AWSRegion appSetting twice in my project web.config file.

I just removed that extra appSetting and keeping all the changes I made and tried redeployment, Voylla it was deployed successfully this time.

So this silly mistake cost my 2-3 days but all well that ends well. So never do such silly mistakes like me 🙂

[SOLVED] AWS S3 – The authorization mechanism you have provided is not supported

Recently I started working on one of my project which I dropped long ago. I was using AWS SDK in this project as this was planned to deploy on AWS.

When I stopped working on this project that time there was no AWS data center in India (Amazon has launched first data center in India which is located in Mumbai). So when I resumed my project (this time I created all my resources in Mumbai region instead of Singapore) again then I get to know that my code is no more working for AWS S3 operations. Every time I tried to do any S3 operations it shows me this error:

The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256

From AWS documentation I get to know that this error is because of API version issue. All new data centers support only latest (v4 at that time) API version and Mumbai data center was one of them. so I download and updated AWS SDK in my project along with updating region in my web config (SDK automatically picks key, secret, region etc by using specified api settings key). But again I got same error.

After searching I get to know that I have to make changes in my code also where I was creating S3 client object because those were required as per the new version of SDK.

Old Code:

AmazonS3Client client = new AmazonS3Client("AWSAccessKey", "AWSSecretKey");

New code

IAmazonS3 client = new AmazonS3Client();

In older version I was supplying key and secret in constructor while creating S3 client object but in new version I used the approach to pick them from web.config (or in app.config if you are woking on desktop application) directly.

Here are the app settings I used in my in web.config which SDK picks automatically:

<add key="AWSRegion" value="ap-southeast-1" />
    <add key="AWSAccessKey" value="AWSAccessKey" />
    <add key="AWSSecretKey" value="AWSSecretKey" />