Use your own Authentication

I didnt want to use Forms Authentication once and I decided to make my own password hashing just for the hell of it, here is a very simple implementation.
The goal was to save a user and the users password as a hash + a random salt string for increased security.
Also wanted to be able to generate a new password and have a hash + salt created for that new password I generated as can be seen from the following interface Crypto.cs.
Note: Yay downloaded a tool that actually Generated HTML from my code properly!! from here.

using System;

using System.Collections.Generic;

using System.Text;

 

namespace PassEncrypt

{

    interface Crypto

    {

        /// <summary>

        ///  Gets the Hash key and Salt for a specific

        ///  password. 

        /// </summary>

        /// <returns>

        /// Will return a string with three elements      

        ///    1. Hash Key

        ///    2. Salt

        /// </returns>

        string[] GenerateKeySalt( string plainTxtPass );

 

 

        /// <summary>

        ///  Change the password.

        /// 

        /// </summary>

        /// <returns>

        /// Will return a string with three elements

        ///    1. New Password

        ///    2. Hash Key

        ///    3. Salt

        /// </returns>

        string[] GenerateNewPassword();

 

        string GetHashKey(string input);

 

    }

}

And now to implement this interface with the Encrypt.cs class (p.s. Man I am lowing this new HTML generation from Code tool):

using System;

using System.Collections.Generic;

using System.Text;

using System.Security.Cryptography;

 

namespace PassEncrypt

{

    public class Encrypt : Crypto

    {

 

        #region Generate the Hash key and salt for a given password

 

        /// <summary>

        /// Returns a salt value and a hash key to be stored

        /// in the database for the given user.

        /// </summary>

        /// <param name=”plainTxtPass”></param>

        /// <returns></returns>

        public string[] GenerateKeySalt(string plainTxtPass)

        {

            string[] s = new string[2];

 

            string salt = GenerateRandomSalt();

            string passAndSalt = plainTxtPass + salt;

            string hash = GetHashKey(passAndSalt);

 

            s[0] = hash;

            s[1] = salt;

            return s;

        }

 

        #endregion

 

        #region Generate a new password

 

        /// <summary>

        /// Generates a new random password and returns a string array with:

        ///    1. new password

        ///    2. hash key

        ///    3. salt value

        /// </summary>

        /// <returns></returns>

        public string[] GenerateNewPassword()

        {

            string[] s = new string[3];

 

            RandomPassword randPassGenerator = new RandomPassword();

 

            string newPass = randPassGenerator.GetPassword();     

            string salt = GenerateRandomSalt();

            string passAndSalt = newPass + salt;

            string hash = GetHashKey(passAndSalt);

 

            s[0] = newPass;

            s[1] = hash;

            s[2] = salt;

 

            return s;

        }

 

        #endregion

 

        #region Generate random salt

 

        /// <summary>

        /// Generates a cryptographically strong salt string

        /// </summary>

        /// <returns></returns>

        public string GenerateRandomSalt()

        {

            RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();

            byte[] saltInBytes = new byte[5];

            crypto.GetBytes(saltInBytes);

 

            return Convert.ToBase64String(saltInBytes);

        }

 

        #endregion

 

        #region Get the hash key for a given string

 

        public string GetHashKey(string input)

        {           

            byte[] tmpSource;

            byte[] tmpHash;

 

            //Convert input to a Byte Array (needed for hash function)

            tmpSource = ASCIIEncoding.ASCII.GetBytes(input);

 

            //Compute hash based on source data.

            tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);

 

            return Convert.ToBase64String(tmpHash);

        }

 

        #endregion

 

    }

}

The following class (RandomPassword.cs) contains my Random password generator. You may want to modify it according to the type of password you would like to generate:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace PassEncrypt

{

    class RandomPassword

    {

        private int RandomNumber(int min, int max)

        {

            Random random = new Random();

            return random.Next(min, max);

        }

 

 

        /// <summary>

        /// Generates a random string with the given length

        /// </summary>

        /// <param name=”size”>Size of the string</param>

        /// <param name=”lowerCase”>If true, generate lowercase string</param>

        /// <returns>Random string</returns>

        private string RandomString(int size, bool lowerCase)

        {

            StringBuilder builder = new StringBuilder();

            Random random = new Random();

            char ch;

            for (int i = 0; i < size; i++)

            {

                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));

                builder.Append(ch);

            }

            if (lowerCase)

                return builder.ToString().ToLower();

            return builder.ToString();

        }

 

 

        public string GetPassword()

        {

            StringBuilder builder = new StringBuilder();

            builder.Append(RandomString(4, true));

            builder.Append(RandomNumber(1000, 9999));          

            return builder.ToString();

        }

 

    }

 

}

Thats all there is to it. I just made this is a class library project names PassEncrypt.

crypto-project.jpg

Just reference PassEncrypt and:
For a new user send their password in and get an array containing the [hash,salt],  store these somewhere and associate them with the username:

    #region Get Hashed password

    public bool GetHashPassword(string username, string password)

    {

        Encrypt crypt = new Encrypt();

        string user = username;

        string pwd = password;

        string salt = “”;

        salt = dataService.GetUserSalt(user);

 

            if (salt != “”)

            {

                string passHash = dataService.GetUserHash(user);

 

                string resultHash = crypt.GetHashKey(pwd + salt);

 

 

                if (passHash == resultHash)

                { //Password Correct

                    return true;

                }

                else

                {

                    return false;

                }

            }

            else

                return false;

    }

    #endregion

Leave a Reply