Recipe 5.8: Transferring Login Credentials Securely

Problem

You need to protect login credentials during transmission
over the network and when they are stored within a database.

Solution

Use password hashing and salting with the .NET FormsAuthentication
class to control user authentication and access to the application.

The schema of table TBL0508 used in this solution is shown in Table
5-5.

Table 5-5. TBL0508 schema

Column name

Data type

Length

Allow nulls?

UserName

nvarchar

50

No

PasswordHash

nvarchar

50

No

PasswordSalt

nvarchar

50

No

The sample code contains two event handlers:

Create Button.Click

Creates a GUID-based salt and generates a hash of the password concatenated
with the salt for a user-specified password. The username, password hash, and
salt are inserted into a database.

Login Button.Click

Retrieves the salt and the hash of the password and salt from the database
for the specified username. The user-entered password is concatenated with the
retrieved salt and the hash is generated. If the hash matches the hash
retrieved from the database, the user is authenticated.

Discussion

Persisting a user's password can be made more secure by first hashing the
password. This means that an algorithm is applied to the password to generate a
one-way transformation—or hash—of the password making it
statistically infeasible to recreate the password from the hash.

A hash algorithm creates a small binary value of fixed length from a larger
binary value of an arbitrary length. The hash value is a statistically unique
compact representation of the original data. A hash value can be created for and
transmitted together with data. The hash can be recreated at a later time and
compared to the original hash to ensure that the data has not been altered. To
prevent the message from being intercepted and replaced along with a new hash,
the hash is encrypted using the private key of an asymmetric key algorithm. This
allows the hash to be authenticated as having come from the sender. For more
information about symmetric and asymmetric key algorithms, see the discussion in
Recipe 5.7. The .NET Framework classes that implement hash algorithms are:

HMACSHA1

MACTripleDES

MD5CryptoServiceProvider

SHA1Managed

SHA256Managed

SHA384Managed

SHA512Managed

In the sample, the user enters his password, the password is hashed, and then
the combination of user ID and password hash are compared to values stored
persistently such as in a database table. If the pairs match, the user is
authenticated, without comparing the actual password. Because the hash algorithm
is a one-way algorithm, the user's password cannot be recreated even if
unauthorized access is gained to the persistent store where the user's password
hash is stored.

The .NET Framework, as part of the FormsAuthentication
class, provides the method HashPasswordForStoringInConfigFile(
) that can hash a password using either SHA1 or MD5 algorithms. The method
is easy to call. It takes two arguments, the password and the hash algorithm,
and returns a string containing the password hash.

Security is never perfect and this technique is no exception. It can be
compromised by a dictionary attack where hash values for most commonly used
passwords are generated. When these values are compared with the hash of the
password and a match is found, the password is then known. To thwart the
dictionary attack, a random string referred to as salt is concatenated with the original password before
generating the hash value. The salt is stored together with the hash of the
password and salt. This makes a dictionary attack much more difficult to
perform.

This web page should be used in conjunction with forms-based authentication.
Additionally, this page should be accessed securely (i.e., https to protect the
plaintext password from client to server).

The most secure technique is useless if the password policy does not prevent
users from choosing easy to guess passwords, or if security is compromised by
users who write passwords down on notes attached to their computer monitors, for example.