Tuesday, September 28, 2010

Are you storing “strong” passwords real strong?

Confused with the above line? Well, have seen many applications which ask users to enter strong password which includes special character and numeric or combination etc. But while storing the password most of the time we convert the password text to hash which is known to be a secure way to store. This approach may be secure in last centuries not any more.  Check out http://en.wikipedia.org/wiki/Rainbow_table the mapping function from hash strings to any possible combinations of keyboard characters (alphanumeric, punctuations, etc.) have rendered this password storage / validation method insecure

Check this post http://www.codinghorror.com/blog/2007/09/rainbow-hash-cracking.html it says “The multi-platform password cracker Ophcrack is incredibly fast. How fast? It can crack the password "Fgpyyih804423" in 160 seconds

How do we strengthen storing password?

Simply provide a random salt while hashing password. Also iterate through many loops which requires extra computing burden to match the password. Normally keep the iteration count to 1000.

Here is how we can achieve that in C#  

using (Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(input, salt, hashIterations))
            {
                byte[] hash = derivedBytes.GetBytes(desiredHashBitSize / 8);
                return hash;
            }


Friday, September 24, 2010

Bitwise computation with C#

If you have written programs in C or C++ , I'm sure you might have used bitwise operators very often. We can use the same thing even in C#. I'm not going to explain the bitwise operators but would take an example of “&” operator and see how it can be used in our programs effectively.

For details on & operator you can check http://msdn.microsoft.com/en-us/library/sbf85k1c.aspx

Let us take an example of logging class where we would need to log based on the configuration. The easiest method to keep the configuration is to specify the highest level of logging required. i.e if we are planning to log exceptions, warnings, Info, Detailed messages then if we specify Detailed messages on the config that indicates all the categories below this level should be considered for logging. If we decide not to log detailed messages and we are okay with info level, then it should log except Detailed messages. How do we do this? We can approach different solutions but easiest one in terms of program maintenance and configuration is to keep the highest level of logging required on configuration and write the program accordingly.  Let us see how we can do this with our C# code.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Diagnostics
{
    public enum LogCategory { None = 0,Exception = 1,Error = 3,Warning = 7,Info = 15 }

    class Log
    {
       
         static Log()
        {
            Log.LogLevel = 7; // read from configuration
        }

        public static LogCategory LogLevel { get; set; }

        public static void Info(string message)
        {
            if ((Log.LogLevel & LogCategory.Info) == LogCategory.Info)
                Write(LogCategory.Info, message, null);
        }
        public static void Info(string message, params object[] parameters)
        {
            if((Log.LogLevel & LogCategory.Info) == LogCategory.Info)
                Write(LogCategory.Info, message, parameters);
        }

        public static void Warning(string message)
        {
            if ((Log.LogLevel & LogCategory.Warning) == LogCategory.Warning)
                Write(LogCategory.Warning, message, null);
        }
        public static void Warning(string message, params object[] parameters)
        {
            if ((Log.LogLevel & LogCategory.Warning) == LogCategory.Warning)
                Write(LogCategory.Warning, message, parameters);
        }

        public static void Error(string message)
        {
            if ((Log.LogLevel & LogCategory.Error) == LogCategory.Error)
                Write(LogCategory.Error, message, null);
        }
        public static void Error(string message, params object[] parameters)
        {
            if((Log.LogLevel & LogCategory.Error) == LogCategory.Error)
                Write(LogCategory.Error, message, parameters);
        }
        public static void Exception(Exception err)
        {
            if ((Log.LogLevel & LogCategory.Exception) == LogCategory.Exception)
            {
                string errMessage = err.Message;
                Write(LogCategory.Exception, errMessage, null);
            }
        }
        public static void Exception(Exception err, params object[] parameters)
        {
            if ((Log.LogLevel & LogCategory.Exception) == LogCategory.Exception)
            {
                string errMessage = err.Message;
                Write(LogCategory.Exception, errMessage, parameters);
            }
        }
        private static void Write(LogCategory ctgy, string message, params object[] parameters)
        {
            // write to text or DB
        }
    }
}



If you look at above class, the log category is defined as 0, 1, 3, 7, 15 … this is actually the bit representation to identify if we need to consider category level.  The bit representation of these numbers as below
0 – 0000 0000
1 – 0000 0001
3 – 0000 0011
7 – 0000 0111
15 – 0000 1111

So if we need to add another level it would be 31 which will represent as
31 – 0001 1111

Hope this will explain why we have these numbers on the enum. Now, let’s look at other methods which are written for logging the messages. All the methods use “&” to check if the message needs to be logged.
If the configuration specifies that we need to log only till warning, and when we try to log info this is what happens

Config = 7

Log.LogLevel & LogCategory.Info
0000 0111 - 7
0000 1111 - 15
0000 0111 – result – that means the Info is not configured here

What happens for Exception when the Log level is set as Warning

Log.LogLevel & LogCategory.Exception) == LogCategory.Exception
0000 0111 - 7
0000 0001 – 1
0000 0001 – result – the exception is matching and its allowed.

I had never used this before and very much interested when I was discussing with one of our developer. Really want to thank him for showing me this amazing piece. 

Thursday, September 9, 2010

Problem opening CHM file?

I had this problem many times whenever I download chm file from internet. Most of the time when I download the file and open it, it says "Navigation to the webpage was canceled" and for a moment I get annoyed thinking how to fix it. The fix is to go to property of the file and unblock the file.