Let me explain with some of the common ways of storing passwords in the database with its demerits. By reading this full article you will understand the best way to secure your password using Cryptographic algorithms in C# .NET.
1. Plain text
Storing password in plain text is the worst way of password management. If the database is compromised by the hacker, with no effort he can reveal all the passwords.
2. Symmetric Key Encryption
One usual way to storing password is using encryption. it's a two-way process. That means the password is encrypted using the secret key when storing and decrypt using the same key for the password authentication.
It's better than storing the password as plain text. But key management is the challenge. Where do you save that key? If it is a database, It won't be difficult for the hacker who got the encrypted password by hacking the database and decrypt it using the same key.
3. Asymmetric Key Encryption
So instead of using symmetric key encryption algorithm. we can use asymmetric key encryption algorithm like RSA where client uses public key to encrypt the password and sends it to the server for storage. When authenticate a private key is used to decrypt the password. That private key should be kept secret. This is also not a great solution as the key management is difficult like the previous way.
4. Hashing
If we use Hashing there won't be any over head of key management. Also no need to decrypt the password back to plain text. As we discussed in my previous article Cryptographic Hashing Algorithm in .NET C#, Hashing is one way operation. Once a data is hashed we cannot reverse and get the original message, It has four important properties,
Two types of attack is possible on the hashed password. They are,
The attacker would try the different combination of passwords hash that is equivalent to the password hash you have stored. Using the latest high performance graphic processor system it is possible to generate billions of random password hash. It only the matter of time to generate the correct password.
Rainbow table attack
A rainbow table is a listing of all possible plain text permutations of hashed passwords specific to a given hash algorithm. Which is often used for crack the password from the hashed values that we stored in the application database. It can be Giga bytes of size. Once an attacker gains access to a system’s password database, the password cracker compares the rainbow table’s precompiled list of hashes to hashed passwords in the database. The rainbow table relate plaintext possibilities with each of those hashes. Thus attacker could crack the password.
5. Salted Hash
It is common for a web application to store in a database the hash value of a user's password. Without a salt, a successful SQL injection attack may yield easily crackable passwords. Because many users re-use passwords for multiple sites, the use of a salt is an important component of overall web application security
If we append a random value with a hashed password, Which is difficult for the attacker to hack using brute force or rainbow table attack. The random value is called Salt. The Salted hash and the Salt will be stored in the database as the Salt is required when the password authentication.
Salted Hash Sample Code :
6. Password Based Key Derivation Function (PBKDF2)
Attackers can use super computers for the brute force attack as it could generate large number of random passwords within a sort period of time. To solve this PBKDF2 is used.
The PBKDF2 expect password input with salt also additionally the number of iteration the password should be hashed. It makes password cracking much more difficult also increase the time taken to generate the hash value. You can see the delay in below sample code based on the number of iteration value u have passed.
When the standard was written in 2000, the recommended minimum number of iterations was 1000, but the parameter is intended to be increased over time as CPU speeds increase. As of 2005 a Kerberos standard recommended 4096 iterations, Apple iOS 3 used 2000, iOS 4 used 10000, while in 2011 LastPass used 5000 iterations for JavaScript clients and 100000 iterations for server-side hashing.
PBKDF2 Sample Code
Storing password in plain text is the worst way of password management. If the database is compromised by the hacker, with no effort he can reveal all the passwords.
2. Symmetric Key Encryption
One usual way to storing password is using encryption. it's a two-way process. That means the password is encrypted using the secret key when storing and decrypt using the same key for the password authentication.
It's better than storing the password as plain text. But key management is the challenge. Where do you save that key? If it is a database, It won't be difficult for the hacker who got the encrypted password by hacking the database and decrypt it using the same key.
3. Asymmetric Key Encryption
So instead of using symmetric key encryption algorithm. we can use asymmetric key encryption algorithm like RSA where client uses public key to encrypt the password and sends it to the server for storage. When authenticate a private key is used to decrypt the password. That private key should be kept secret. This is also not a great solution as the key management is difficult like the previous way.
4. Hashing
If we use Hashing there won't be any over head of key management. Also no need to decrypt the password back to plain text. As we discussed in my previous article Cryptographic Hashing Algorithm in .NET C#, Hashing is one way operation. Once a data is hashed we cannot reverse and get the original message, It has four important properties,
- Easy to compute the hash value for any given message
- Not possible to generate a message from the given hash
- Not possible to modify a message without changing the hash
- Not possible to find two different messages with the same hash
Two types of attack is possible on the hashed password. They are,
- Brute force attack
- Rainbow table attack
The attacker would try the different combination of passwords hash that is equivalent to the password hash you have stored. Using the latest high performance graphic processor system it is possible to generate billions of random password hash. It only the matter of time to generate the correct password.
Rainbow table attack
A rainbow table is a listing of all possible plain text permutations of hashed passwords specific to a given hash algorithm. Which is often used for crack the password from the hashed values that we stored in the application database. It can be Giga bytes of size. Once an attacker gains access to a system’s password database, the password cracker compares the rainbow table’s precompiled list of hashes to hashed passwords in the database. The rainbow table relate plaintext possibilities with each of those hashes. Thus attacker could crack the password.
5. Salted Hash
It is common for a web application to store in a database the hash value of a user's password. Without a salt, a successful SQL injection attack may yield easily crackable passwords. Because many users re-use passwords for multiple sites, the use of a salt is an important component of overall web application security
If we append a random value with a hashed password, Which is difficult for the attacker to hack using brute force or rainbow table attack. The random value is called Salt. The Salted hash and the Salt will be stored in the database as the Salt is required when the password authentication.
Salted Hash Sample Code :
using System; using System.Security.Cryptography; using System.Text;
static void Main() { const string password = "SampleP455w0rd"; byte[] salt = GenerateSalt(); Console.WriteLine("Sample Password : " + password); Console.WriteLine("Generated Salt : " + Convert.ToBase64String(salt)); Console.WriteLine(); var hashedPassword = HashPasswordWithSalt(Encoding.UTF8.GetBytes(password), salt); Console.WriteLine("Salted Hash Password : " + Convert.ToBase64String(hashedPassword)); Console.WriteLine(); Console.ReadLine(); }
public static byte[] GenerateSalt() { const int saltLength = 32; using (var randomNumberGenerator = new RNGCryptoServiceProvider()) { var randomNumber = new byte[saltLength]; randomNumberGenerator.GetBytes(randomNumber); return randomNumber; } }
private static byte[] Combine(byte[] first, byte[] second) { var ret = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, ret, 0, first.Length); Buffer.BlockCopy(second, 0, ret, first.Length, second.Length); return ret; }
public static byte[] HashPasswordWithSalt(byte[] toBeHashed, byte[] salt) { using (var sha256 = SHA256.Create()) { var combinedHash = Combine(toBeHashed, salt); return sha256.ComputeHash(combinedHash); } }Console Output
6. Password Based Key Derivation Function (PBKDF2)
Attackers can use super computers for the brute force attack as it could generate large number of random passwords within a sort period of time. To solve this PBKDF2 is used.
The PBKDF2 expect password input with salt also additionally the number of iteration the password should be hashed. It makes password cracking much more difficult also increase the time taken to generate the hash value. You can see the delay in below sample code based on the number of iteration value u have passed.
When the standard was written in 2000, the recommended minimum number of iterations was 1000, but the parameter is intended to be increased over time as CPU speeds increase. As of 2005 a Kerberos standard recommended 4096 iterations, Apple iOS 3 used 2000, iOS 4 used 10000, while in 2011 LastPass used 5000 iterations for JavaScript clients and 100000 iterations for server-side hashing.
PBKDF2 Sample Code
using System; using System.Diagnostics; using System.Security.Cryptography; using System.Text;
static void Main() { const string passwordToHash = "SamplePassword"; HashPassword(passwordToHash, 100); HashPassword(passwordToHash, 50000); HashPassword(passwordToHash, 500000); Console.ReadLine(); }
private static void HashPassword(string passwordToHash, int numberOfRounds) { var sw = new Stopwatch(); sw.Start(); var hashedPassword = HashPassword(Encoding.UTF8.GetBytes(passwordToHash), GenerateSalt(), numberOfRounds); sw.Stop(); Console.WriteLine("Password to hash : " + passwordToHash); Console.WriteLine("PBKDF2 Hashed Password : " + Convert.ToBase64String(hashedPassword)); Console.WriteLine("Iterations : " + numberOfRounds); Console.WriteLine("Elapsed Time : " + sw.ElapsedMilliseconds + "ms"); Console.WriteLine(); }
public static byte[] GenerateSalt() { using (var randomNumberGenerator = new RNGCryptoServiceProvider()) { var randomNumber = new byte[32]; randomNumberGenerator.GetBytes(randomNumber); return randomNumber; } }
public static byte[] HashPassword(byte[] toBeHashed, byte[] salt, int numberOfRounds) { using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(toBeHashed, salt, numberOfRounds)) { return rfc2898DeriveBytes.GetBytes(32); } }Console Output
I am in fact grateful to the owner of this web site who has shared this enormous piece of writing at
ReplyDeletehere.
Rattling clean website, thanks for this post.
ReplyDeleteThis design is spectacular! You most certainly know how to keep a reader
ReplyDeleteamused. Between your wit and your videos, I
was almost moved to start my own blog (well, almost...HaHa!) Excellent job.
I really loved what you had to say, and more
than that, how you presented it. Too cool!
I have been exploring for a little bit for any high-quality articles
ReplyDeleteor weblog posts in this sort of house . Exploring in Yahoo I
finally stumbled upon this website. Studying this information So i'm satisfied to convey that I have
a very good uncanny feeling I discovered exactly what I needed.
I such a lot unquestionably will make sure to do not forget this website and provides it a glance on a
relentless basis.
Hey I am so delighted I found your blog, I really found you by
ReplyDeletemistake, while I was looking on Yahoo for something else,
Anyhow I am here now and would just like to say cheers for
a incredible post and a all round entertaining blog (I also
love the theme/design), I don't have time to browse it all at the moment but I have bookmarked it
and also added in your RSS feeds, so when I have time I will be back
to read more, Please do keep up the superb job.
hi!,I really like your writing very so much!
ReplyDeletepercentage we keep up a correspondence extra about your article
on AOL? I need a specialist in this house to solve my problem.
May be that is you! Looking forward to see you.
Normally I do not read post on blogs, but I wish to say that this write-up very forced me to check out and do it!
ReplyDeleteYour writing style has been surprised me. Thank you, very great article.
hello!,I love your writing so a lot! proportion we
ReplyDeletekeep in touch more approximately your article on AOL? I require an expert in this house to resolve my problem.
May be that's you! Looking forward to peer you.
I truly appreciate this post. I have been looking everywhere for this!
ReplyDeleteThank goodness I found it on Bing. You have made my day!
Thx again!
Oh my goodness! Incredible article dude! Thanks, However I am having troubles with
ReplyDeleteyour RSS. I don't know why I cannot subscribe to it. Is there anybody
else getting similar RSS issues? Anybody who knows the answer will you kindly
respond? Thanx!!
Hi, what about decrypt?
ReplyDeleteHow can decrypt after encryption done with your algorithm?
Please respond.
How to use Password Based Key Derivation Function (PBKDF2) in Login form? As It is every time generate new key? How to compare with old stored encrypted password?
ReplyDelete