What is the difference between bcrypt and SHA256?
TL;DR; SHA1, SHA256, and SHA512 are all fast hashes and are bad for passwords. SCRYPT and BCRYPT are both a slow hash and are good for passwords. Always use slow hashes, never fast hashes.
SANS' Securing Web Application Technologies [SWAT] Checklist is offering a bit of bad security advice for the everyday web application developer, under the heading “Store User Passwords Using A Strong, Iterative, Salted Hash”:
User passwords must be stored using secure hashing techniques with a strong algorithm like SHA-256. Simply hashing the password a single time does not sufficiently protect the password. Use iterative hashing with a random salt to make the hash strong.
The SANS Institute is well recognized information security and cybersecurity training organization that helps educate companies on how to be more secure. The SWAT, like the OWASP ASVS, is designed to help blue team developers do their jobs better by not forgetting about common issues, such as those discussed in the OWASP Top 10.
However, for this instance it is not recommended that regular web applications use any member of the SHA family, be it SHA1, SHA256, or even SHA512 for password hashing. The reason is that all of these hashes are fast hashes. When an attacker gets access to your database of password hashes and he also has a copy of your salt, which he presumably will considering that your server was compromised, then your users' passwords are in danger. With a fast hash, the attacker can compute billions of hashes per second in an offline attack.
The recommendation does bring up the concept of rounds, but most developers should not be making these tradeoff decisions. 5-10 rounds of a fast hash are still not slow enough to protect from an offline attack. At best it is an extra measure of security through obscurity. Your users do not stand a chance on average and a large number of them use the same passwords on other websites, including their banks. It is bad.
Fortunately, there is a class of slow hashes designed just for passwords. One of the most accessible is bcrypt. It’s the default password hash used by Devise and Ruby on Rails' has_secure_password. It is an open standard that is available on many platforms including .NET and Java. Another excellent choice is scrypt, which is available on many platforms and in some ways is better than bcrypt against offline brute force attacks.
Anyway, back to the SANS question. After seeing this piece of advice I had to say something, so after not seeing the best way to contact the editor through the website, I reached out via Twitter to @sansappsec.
@sansappsec Who do I contact about an item on the SWAT that in my opinion is providing less than best security advice?
— Frank Rietta, MSIS (@frankrietta) February 4, 2016
@sansappsec Specifically, bcrypt is a specific password hash that's better than multiple rounds of the SHA family, which are fast hashes.
— Frank Rietta, MSIS (@frankrietta) February 4, 2016
@frankrietta thanks for the input. We'll update the next version
— SANS AppSec (@sansappsec) February 4, 2016
I’m always happy to help get good information out to my fellow developers to write more secure applications!
{% render_partial _includes/callouts/_web_topics_issue.md %}
Revision History
As a maintained post, this document is updated from time to time.
- June 6, 2016: Added information about scrypt that is a slow hash appropriate for passwords that shares many characteristics with bcrypt.