Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice of Hashing passwords

I would like to know which method to use to store passwords in database. I have implemented it using MD5 but according to some posts SHA1 is more secure. Is there any other method which is more secure? Please help me finding out a best method to secure passwords.

like image 284
Arti Avatar asked Nov 25 '13 06:11

Arti


People also ask

Is SHA-256 good for password hashing?

SHA-256 is one of the most secure hashing functions on the market. The US government requires its agencies to protect certain sensitive information using SHA-256.

What is the most convenient hashing method to be used to hash passwords?

So that's why we use various hashing methods to hash passwords to secure our passwords while creating websites and storing our database. In PHP, there are various cryptographic algorithms that are commonly used like md5, crypt, sha1, and bcrypt. And the most commonly used nowadays is bcrypt hashing method.

Is sha512 better than SHA-256?

The reason why SHA-512 is faster than SHA-256 on 64-bit machines is that has 37.5% less rounds per byte (80 rounds operating on 128 byte blocks) compared to SHA- 256 (64 rounds operating on 64 byte blocks), where the operations use 64-bit integer arithmetic.


2 Answers

Sure SHA1 is more secure that MD5, but for most purposes it is not secure enough.

You will probably find useful the video How NOT to Store Passwords by Computerphile - 9 minutes and 24 seconds long.

You must realize that there is much to cover when it comes to authentication and access control, so having a good hashing scheme is not enough.


On storing passwords.

As you already know, you don't store the password. In fact, when it comes to storing passwords, in general terms you want to store salted hashes of the passwords, using a modern algorithm optimized for this purpose. For the salt it is considered ok to store it alongside to the hash, for the salt value use a random value as long as possible.

Note: When generating random value for security purposes, use a cryptographic secure generator (such as a subclass of RandomNumberGenerator for .NET - example). This random number generator are designed to be hard to predict. While standard random number generator are meant to be repeatable (That is with System.Random all you need is the seed to generate all the values, and to guess the seed all you need is enough consecutive values generated with the same seed).

Also note: Most hashes are optimized to be fast to calculate, in that category falls both MD5 and SHA1. You should choose one that is not that fast, so that the attack will take a reasonable amount of time to compute the hashes when trying to crack your passwords.

One such algorithm is BCrypt - others include Scrypt and PBKDF2 - on using BCrypt from C# you will find the article Use BCrypt to Hash Your Passwords: Example for C# and SQL Server useful. If you can't resource to BCrypt or similar algorithm, you should atleast use a variant of SHA2 (SHA256, SHA512 and so on).

Addendum: You can use the class HMACSHA256 which is available in the BLC as a key derivation function, pass your salt as key. This is preferible to appending or prepending the salt (which could fall to Length extension attacks). That is, if you use HMAC, and your hash algorithm is vulerable to Length extension attacks (known or to be discovered), your system is till secure. MD5, SHA1 and SHA2 as suceptible to this kind of attack. SHA3 is not. Sadly SHA3 is not included in the BLC (no, it is not SHA384), you can get it from Multiformats.Hash or HashLib. I have to mention that SHA3 is also designed to be fast when implemented in hardware. And remember, for passwords an slow hash is better.


Addendum: Argon2

As it was pointed a year ago this answer should be updated to mention of Argon2. I did write the original answer before that existed.

At the time, I had not found an implementation for C# that I was willing to recommend. Since this answer was brought to my attention, I had another look, and that is no longer the case.

You can use Isopoh.Cryptography.Argon2 which has fully managed code (it is not a C# binding for a C++ implementation, but full C# code), works on all major platforms and there are Nugets available.

Notes:

  • Use Argon2Version.Nineteen. This is Argon2 v.1.3 (Nineteen = 0x13) which fixes known vulnerabilities.
  • Use Argon2Type.DataDependentAddressin (Argon2d), or use Argon2Type.DataIndependentAddressing (Argon2i) with TimeCost >= 10. Argon2d is in theory vulnerable to side channel attacks, as such it is not recommended for code that runs on client machines. Isopoh.Cryptography.Argon2 mitigates this by using OS calls to prevent sensitive memory to be moved to virtual memory/pagefile/swap and zero it as soon as possible. On the other hand Argon2i has a Time-memory tradeoff vulnerability, which allows to compute the hashes faster by using more memory. The paper Towards Practical Attacks on Argon2i and Balloon Hashing shows that you need 10 iterations/passes to make the exploit inefficient, even in Argon2 v.1.3.

Here are some recommended reading:

  • Speed Hashing
  • You're Probably Storing Passwords Incorrectly
  • Everything you ever wanted to know about building a secure password reset feature
  • The definitive guide to form based website authentication
  • OWASP's Password Storage Cheat Sheet
  • OWASP's Forgot Password Cheat Sheet

Also the video: Crypto is Back! - Google Tech Talk - August 5, 2009 - 54 minutes and 32 seconds long.


On recovering a password.

First off: don't. The point of the password recovery option is not to recover the password, but to recover access to the application. So... how do you recover access to the application?

I'm glad you ask. What you need is an alternative way to verify the identity of the user. This could be a second factor authentication (anything from security question to using a hardware key generator). Yet, what is often done is to resource on third party, such as mail.

So, you want to know if the user is the owner of the email (or cellphone, or whatever) the user has previouly claim to own. In order to do so you send a code (often refered as token or cookie) to that email (or whatever). This must be a random generated code with a cryptographic secure generator so that nobody else - except the owner of that email (or whatever) - will be able to know what that code is.

Now, if the user presents to your application that code, you are almost sure it is the right user.

Almost because: emails (or whatever) could has been stored in an unsecure location. To mitigate that, you want to put a time limit on your code (cookie or token). Also, if a code has been used, it should NOT work again. And for extra security you could resource to a CAPTCHA, to ensure this code doesn't come from a bot that just got lucky.

For more on this topic (this links are also presented above):

  • Everything you ever wanted to know about building a secure password reset feature
  • OWASP's Forgot Password Cheat Sheet
like image 54
Theraot Avatar answered Nov 05 '22 12:11

Theraot


SHA1 has less vulnerabilities than MD5. It's a newer algorithm that utilizes more bits and requires more processing to "crack." You can view most of the mainstream hash algorithms and their known vulnerabilities here: http://en.wikipedia.org/wiki/Cryptographic_hash_function

As someone already commented, definitely make sure you add "salt" to your password hash to further obscure any possible pattern.

like image 42
cygnim Avatar answered Nov 05 '22 12:11

cygnim