Simple, Yet Effective .NET Password Hashing

password hashing

Your company’s data is the most valuable asset you own. From personnel files to proprietary information, if the files your business keeps wind up in the wrong hands, the consequences could be disastrous.

An oft overlooked area of security, especially in website development, is making sure all the passwords created for the site are secure. While some employees might grumble at the thought of having to change their passwords routinely, or having to create one that features letters (both upper and lower case), numbers, and symbols, the safety of your company’s data is at stake.

One of the best ways to protect the passwords your company uses is through password hashing.

Encryption vs. Password Hashing

The difference between encryption and hashing is often confused. The phrase “make sure the passwords are encrypted” often gets used. Encryption is the process of using an algorithm with a key to secure data while allowing for the data to be decrypted later. The effectiveness of encryption depends on speed and the amount of difficulty required to break it without a key.

Password hashing, on the other hand, is a one-way process intended to be very difficult to reverse, adding small variations of code to the password thereby making a hacker’s job much more challenging. Afterward, the password comes out looking significantly different in its “hashed form.”

When a user sets a password, it is hashed and becomes a stored numeric byte sequence. When the same user attempts to log in later, the password they enter at that time is hashed using the same process. If the password matches the hash stored previously, it’s accepted. If not, it’s rejected.

Password hashing is a one-way process intended to be slow and difficult to reverse.

While encryption can be used for passwords, it poses a significant risk in that it uses a fixed key. If the key should ever be compromised, it would allow an attacker to decrypt any stored passwords obtained during a breach. With password hashing, if an attacker does obtain the list of usernames and hashed passwords, it will be extremely difficult to reverse them into usable passwords. In this instance, the passwords are still safe.

Password Hashing Isn’t Unbreakable

While hashing is a great practice, it isn’t impervious to attacks. As with encryption, hashes can be broken given sufficient time and computing power, so saying it’s unbreakable is somewhat misleading. The goal in creating a good password hashing algorithm is to make it so any attempt to reverse the hash would require extreme amounts of time and computing power, making the overall effort not worth the time or expense.

Hashing algorithms are generally run through multiple iterations – sometimes thousands of times.

Salt and Rainbow Tables

You might have heard the term “salt” mentioned in discussions of cryptography. A salt is random data added to the code that greatly increases the strength of hashing by preventing the ability to reverse hashes using rainbow tables.

Rainbow tables are made up from a list of pre-generated hashes from passwords that use variations of common dictionary words. Any salt used must be stored along with the hashed password so that it can be used later for the hashing entered passwords for verification.

For example, take a system that uses a weak hashing of few iterations, with no salt, and allows users to create weak passwords, such as “password1.” An attacker gains access to the usernames and hashes, and, using a rainbow table, has various hashing algorithms for every dictionary word followed by any one-digit number. It doesn’t take long before the hash value in their table finds a match for “password1.” The attacker now has access to your files.

Adding random salt data breaks such lookup tables, since it would require a lookup table for every random salt combination. This table would take many years to generate, and would be far too large to store or use effectively. This is further strengthened by using a sufficiently high number of iterations when hashing.

The use of such pre-generated tables is one reason why it is important to also require users to create strong passwords containing mixed case, alpha numeric characters along with strong hashing.

Simple Example Using C#

Let’s take a look at two simple methods, using C#, to handle password hashing using .NET Framework classes.

The first method takes a password and outputs a generated hash and salt as a Base64 encoding string to allow for easy database storage. The salt is 64 bytes (which is the current recommend minimum), and is created using the RNGCryptoServiceProvider class. This class is designed to create pseudo-random number sequences suitable for cryptographic use.

Next, the Rfc2898DeriveBytes class is used to generate the hash using the RFC2898 specification, which uses a method known as PBKDF2 (Password Based Key Derivation Function #2) and is currently recommend by the IETF (Internet Engineering Task Force) for new applications.

10,000 iterations are used for hashing, which is the current recommendation under NIST guidelines. The call to GetBytes requests a 256-byte key. The output hash and salt are then stored to verify against future entered passwords.

password hashing

The second method is used to verify a password against the stored hash and salt. It takes the entered password, performs the same hash process using the stored salt, and returns true if the password is correct. The password is correct if the hash generated from the entered password matches the one stored.

password hashing

For additional details on PBKDF2 and related hashing algorithms, the full RFC2898 specification is available here.

Password Hashing Help from the Professionals

If you are concerned about hackers attacking your website or emails and would like to talk more about password hashing, the team here at KTL Solutions is happy to help.

Contact us today to see just how we can help your company succeed.