Prologue
If you want to save a password somewhere, but you want to play it save (as you always should do) you should use a hashing algorithm. If you use a hash you save the "signature" of the password instead of the password itself. Then when someone wants to log in you create a hash of the input password and compare it to the hash saved in the database. Then when the hashes are the same it means the original passwords are the same!
The good thing about a hash is that is can't be reversed. So even if a hacker gets a hold on your database he still can't figure out what the original passwords are and thus not a big harm is done.
The example
I have created an example project in ASP.NET MVC 4 which contains a simple log in system which uses an SHA512 hashing algorithm to store the passwords in the database.
The example project can be found on my skydrive.
If you run the example you see a standard project allot like the standard MVC template. I edited a few things, foremost the log in / register system. If you click on Register in the top right corner you can see the most basic register form there is. Same for the Log in form. After you have registered your account you are directly logged in. Just play around a bit.
Error?
If you get the following error when trying to register a user for the first time:
Can't register user right now
This means that the database file can't be created. To fix this issue start Visual Studio with administrator rights. Then the file can be created. After that you can run the application normal.
The code
Now we will take a look in the code, we will start with the following:
Account controller
The account controller is nothing special, you can login, register and go to manage. The first 2 do the most, the manage page is nothing more than a page you can't get to unless you are logged in, no further use. I'll skip too the Login method that handles the login page (method signature: ActionResult Login(LoginModel model, string returnUrl)
). As you can see it is a very small method that uses the Security
class. The same for the Register method (method signature: ActionResult Register(RegisterModel model)
). This method also makes extensive use of the Security
class.
Security class
This class can be found in the Helpers folder. This class contains the following methods:
Login
Logout
CreateUser
The names speak for themselves, first the Login
method. The method begins with a standard check if the arguments are filled in. After that it creates a dbContext
which can be used to access the database. Then we ask for a user from the database that has the entered name, if the user doesn't exist it means that the user does not exist so we return false. If the user does exist we check if the hash in the database is the same as the hash of the entered password, if so we set the cookie that the user is logged in and we return true. If not, we return false because the passwords don't match.
Then there is the Logout
method. This method only calls the SignOut
method of the FormsAuthentication
so the cookie will be removed.
End the last method is the CreateUser
method. This method also starts with checking the arguments of the function, then creating a dbContext
and checking if the user name is already in use. If there is already a user with that name we return that message along to the Register
method from the AccountController
. Else we are free to create the user, generate the hash of the password, save it to the database and return succes as a result.
For the generation and checking of the hash the Security
class used the SHA512Hash
class. This class can also be found in the Helpers folder.
SHA512Hash class
In the current project only 2 of the 4 methods in the hash class are used. But you can use this class whenever you like, as long as you keep the license in mind. This class is nothing more then a simple wrapper around the .NET functions for hashing.
The function string GetHash(string input)
computes the hash from the string and then turns the byte array in a hexadecimal string which it returns.
The function byte[] GetByteHash(string input)
only computes the hash from the string and returns the byte array.
The function bool VerifyHash(string input, string hash)
gets the hash of the input and then compares it to the other hash. The same goes for the bool VerifyHash(string input, byte[] hash)
function.
Conclusion
As you can see it is quite easy to work with hashes when making a log in system. You can even provide more security by using salts. But more about that later or if you wish you could google it or read about in on wikipedia.