Hot Tip
LANGUAGE: C#
ASP.NET VERSIONS: 1.0 | 1.1
Hash Passwords for Added Security
No amount of security is too much.
By Jeff Prosise
We've all seen ASP.NET forms authentication examples that validate credentials typed into a login form against a database of user names and passwords. Such examples often include code like this, which uses a stored procedure named "proc_IsUserValid" to determine whether the database contains a record with a matching user name and password:
// Assume username is the user name the user typed
// Assume password is the password the user typed
// Assume connection is an open SqlConnection
SqlCommand command = new SqlCommand
("proc_IsUserValid", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add ("@UserName", username);
command.Parameters.Add ("@Password", password);
SqlParameter result = command.Parameters.Add
("@Result", SqlDbType.Bit);
result.Direction = ParameterDirection.ReturnValue;
bool valid = (bool) command.ExecuteScalar ();
For added security, you should never store plain text passwords in a login database. Instead, you should store password hashes. That way, if a hacker breaches the defensive perimeter around your Web server and gains access to the database, he or she still doesn't have the user names and passwords needed to hack even deeper. (By definition, it's mathematically impossible - or at least impractical - to work backward from a 1-way hash to the value used to generate it.) The .NET Framework's FormsAuthentication.HashPasswordForStoringInConfigFile makes generating password hashes a snap. Here's a modified sample that uses the SHA-1 hashing algorithm to hash the password the user entered before using it in a database query:
SqlCommand command = new SqlCommand
("proc_IsUserValid", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add ("@UserName", username);
command.Parameters.Add ("@Password",
FormsAuthentication.HashPasswordForStoringInConfigFile
(password, "SHA1"));
SqlParameter result = command.Parameters.Add
("@Result", SqlDbType.Bit);
result.Direction = ParameterDirection.ReturnValue;
bool valid = (bool) command.ExecuteScalar ();
When it comes to security, no amount is too much. Storing password hashes rather than real passwords provides an extra measure of security that might prove valuable someday.
Jeff Prosise is author of several books, including Programming Microsoft .NET (Microsoft Press). He also is a co-founder of Wintellect (http://www.wintellect.com), a software consulting and education firm that specializes in .NET. Contact Jeff at [email protected].