How To Encrypt Passwords Using SHA-256 In C# And .NET

Written by
Published on
Modified on
Category

.NET makes it pretty simple to work with data encryption with the Cryptography namespace. So there should be no reason to have plain text passwords in your databases, like I've seen far too many times at various companies that I've worked for.

And we've read countless times about companies getting hacked, so taking any extra measures to protect your data is important. Or for any other of your data encryption needs.

While the odds of someone taking over your database aren't exactly super high, it is possible, and you want to lower the amount of damage done to your users/clients as much as you can.

The Basic Process

The overall process is relatively simple and will go like this: A user will enter their password on your website, but we won't be storing this password anywhere. Instead we're going to calculate the SHA256 hash and then store that instead. This makes it pretty much impossible to retrieve the users password back, since we don't actually have it.

The tiniest change to a string will create unpredictable changes to the resulting SHA256 hash. So when a user attempts to log in to their account, you recalculate the hash with the value that they have entered and compare the result with what's in the database. If both hashes are the same, then bingo, the user is valid.

You don't have to use the SHA256 variation algorithm to encrypt passwords mind you. But you should pick one, any one, and never store the users passwords in plain text. Many websites still do this, and you can tell because when you attempt to retrieve your password, they will send it right back to you no problem. If they were encrypting your passwords properly, this would not be possible.

Compute Hash

First off we need to specify the correct namespace to do our work in C# and .NET

using System.Security.Cryptography;

The System.Security.Cryptography namespace houses classes involving the encoding and decoding of data, hashing algorithms as well as random number generation.

We'll need to create a new instance of the SHA256 class to work with. However, SHA256 is an abstract class so we will need to use the static class SHA256Managed in order to initialize a SHA256 hash object.

We'll be putting the result in a byte array, because that's what the ComputeHash function, which handles the encoding, returns as its calculated value. The byte array will result in 256 bits of data (hence SHA256), which translate to a 32 byte array.

We'll also need to create a new object of type UTF8Encoding which will take the string representation of our data and convert it to a byte array using the GetBytes(string) method.

private byte[] CalculateSHA256(string str)
{
        SHA256 sha256 = SHA256Managed.Create();
        byte[] hashValue;
        UTF8Encoding objUtf8 = new UTF8Encoding();
        hashValue = sha256.ComputeHash(objUtf8.GetBytes(str));

        return hashValue;
}

Most of the hashing algorithms in .NET will follow the same pattern of creating a new managed object and computing the hash on the byte interpretation of the data.

Storing The Hash

So now that you have the encrypted value you'll need to store that byte array into the database. If you're working with SQL Server than you can create a new column with a Data Type of binary(32), because the result is 32 bytes long. If you're working with any other DBMS, than you'll have to lookup the equivalent to a 32 byte array.

Comparing Hashes

So now when a user logs in with their password, you'll start off by calculating a hash for that password and then comparing it with the value that is stored in the database. If both values end up matching then we have a winner.

Adding A Salt

This is totally optional, but recommended to make it harder for would be intruders to figure out your stored passwords. A salt is extra data that is appended to a string before it is encrypted. For example:


Pre-Salt: password1234

With Salt: password1234k44LD8Ew90

The appended string can be any random set of characters that you define and should be different for every user. It's an extra level of protection because the users password alone is not enough to calculate the hashed value. Any attacker would also have to know the users salt in order to compare values.

It's just a few extra steps in order to better protect your websites and you'll feel better knowing that your users are that much more protected and they'll feel better knowing that your website cares about their security.

Comments

R
7/31/2020 6:51:56 AM
This is a great example. Was easy to convert to VB! TY
Walter Guevara is a software engineer, startup founder and currently teaches programming for a coding bootcamp. He is currently building things that don't yet exist.

Developer Poll 🐱‍💻

Q:

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post