Author

Topic: Password Hashing and Storage (Read 1212 times)

legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
August 16, 2012, 10:56:52 PM
#12
If you hash something and then hash the resulting hash, the combined "doubleHash" algorithm is slightly weaker against certain attacks than just hashing the data once. Every additional hash round weakens it more. You need to at least mix the password back in during each round:

Code:
for(int round = 0; round < 1000; ++round)
    result = hash(result + password);

That method of getting salt seems secure, but it'd be easier and even more secure to just use some random data stored with the password.

It's best to use established algorithms like SHA256-crypt, though. These use even more mixing to prevent cryptanalysis.

Thanks for the tip - I will be changing the hashing rounds per this advice.

The main reason for the salt being generated the way it is (i.e. from the username) is that I have designed my system to provide security over HTTP (so all information needed to create the salt needs to have been first broadcast).

Am using SHA-1 currently (as it was the only secure hash algo I had previously) but will be changing to it later.
donator
Activity: 1218
Merit: 1079
Gerald Davis
August 16, 2012, 10:52:51 PM
#11
To anyone clinging to outdated ideas like using SHA-1 (or SHA-256/512, RIPEMD-160, etc) for storing passwords a simple question to ask yourself.  
Does your login server need to be able to process 4 billion logins per second?  No?  
Then why are you using a algorithm which allows the hacker to brute force at the rate of 4 billion attacks per second?  

Use an algorithm like bcrypt and pick a workload so that your login throughput is only say 20 logins per second (@ 10% cpu load).   That means the average CPU based attacker can attempt couple hundred attacks per second, and the average GPU a mere couple thousand attacker per second.  

Bcrypt is no better at "being slow" than SHA-based password hashing schemes. When you increase bcrypt's difficulty factor, you're just increasing the number of times a hash-like algorithm is applied to the data. It's exactly the same as increasing the number of rounds in SHA256-crypt. I prefer SHA2-based schemes because SHA-2 was specifically designed for things like password hashing, and its use is recommended by many standards.

There is nothing wrong with using PBKDF2 (a solid multi-round algorithm which can use SHA-256 among other hashes).  However most users attempting to roll their own multi-round SHA function will likely create vulnerabilities.  First they will under estimate how fast SHA-256 is.  100 rounds or even 1,000 rounds is worthless.  For brute force resistance one needs hundreds of thousands of rounds.  Second they likely will introduce vulnerabilities like creating intra-round collisions.    They may underestimate the need for salt or the size of the salt.  They may try to do things like derive the salt from low entropy sources, etc.  The advantages of PBKDF2, bcrypt, and scrypt is they are end to end solutions.   password in -> solid multi-round cryptography -> hash out.

PBKDF2 (using SHA-256) is well tested and a good alternative to bcrypt, but bcrypt has an advantage of limiting attacker's hardware advantage.   Even a single round of bcrypt (blowfish) is roughly 1,000x slower than a single SHA-256 hash and bcrypt doesn't optimize well on GPUs.  The average GPU is in the ballpark of ~100x as fast as the average CPU when it comes to SHA-256 hashing but only ~5x as fast with bcrypt.  Since most servers are using CPU picking an algorithm which is optimized for GPU doesn't aid the server any but it certainly does aid the attacker. bcrypt creates a more level playing field and that hurts the attacker.

That being said nothing wrong with PBKDF2 as an alternative to bcrypt. My post was more about single round SHA-256.
administrator
Activity: 5222
Merit: 13032
August 16, 2012, 10:52:39 PM
#10
Am just wondering if there is any weakness in the approach that I am using?

If you hash something and then hash the resulting hash, the combined "doubleHash" algorithm is slightly weaker against certain theoretical attacks than just hashing the data once. Every additional hash round weakens it more. You should at least mix the password back in during each round:

Code:
for(int round = 0; round < 1000; ++round)
    result = hash(result + password);

That method of getting salt seems secure, but it'd be easier and even more secure to just use some random data stored with the password.

It's best to use established algorithms like SHA256-crypt, though. These use even more mixing to prevent cryptanalysis.
administrator
Activity: 5222
Merit: 13032
August 16, 2012, 10:42:11 PM
#9
To anyone clinging to outdated ideas like using SHA-1 (or SHA-256/512, RIPEMD-160, etc) for storing passwords a simple question to ask yourself. 
Does your login server need to be able to process 4 billion logins per second?  No? 
Then why are you using a algorithm which allows the hacker to brute force at the rate of 4 billion attacks per second? 

Use an algorithm like bcrypt and pick a workload so that your login throughput is only say 20 logins per second (@ 10% cpu load).   That means the average CPU based attacker can attempt couple hundred attacks per second, and the average GPU a mere couple thousand attacker per second. 

Bcrypt is no better at "being slow" than SHA-based password hashing schemes. When you increase bcrypt's difficulty factor, you're just increasing the number of times a hash-like algorithm is applied to the data. It's exactly the same as increasing the number of rounds in SHA256-crypt. I prefer SHA2-based schemes because SHA-2 was specifically designed for things like password hashing, and its use is recommended by many standards.
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
August 16, 2012, 10:37:46 PM
#8
Brute force attacks are done against the db.  No server side code is going to stop that.  Honestly password878 is likely strong enough against an attacker trying to login as you.  Of course no attacker tries to login as you.

Salt isn't a secret.  Salt is designed to limit the attacker to 1 account per hash in realtime.  Nothing more.

Currently I am encrypting password hashes (with AES) based upon a key that is split between compiled C++ code and a the contents of a text file - so there is nothing to help you crack a password if you just grabbed the DB contents.

The salt that I use (currently) is the username hashed by x rounds and combined with a unique server id string (also not stored in the DB) and the final password hash itself being y rounds of the salt and actual password.

Am just wondering if there is any weakness in the approach that I am using?
donator
Activity: 1218
Merit: 1079
Gerald Davis
August 16, 2012, 10:26:31 PM
#7
To anyone clinging to outdated ideas like using SHA-1 (or SHA-256/512, RIPEMD-160, etc) for storing passwords a simple question to ask yourself.  
Does your login server need to be able to process 4 billion logins per second?  No?  
Then why are you using a algorithm which allows the hacker to brute force at the rate of 4 billion attacks per second?  

Actually I don't think that the algorithm is so important as limiting the # of attempts to login to the same account (as is done by banks) - it would be a pretty stupid piece of software that actually allows even 100 attempts to login to the same account within minutes.


Brute force attacks are done against the db.  No server side code is going to stop that.  Honestly password878 is likely strong enough against an attacker trying to login as you.  Of course no attacker tries to login as you.


In my opinion password salts have limited usefulness if they are stored right next to the passwords. I say this because if you know the salt and how it's applied to the password then the work of the gpu finding the password is really just the work of scanning passwords. The salt is irrelevant since it takes so little time to calculate. I don't have a good solution off-hand for how to store salts separately or generate them as needed.

That isn't the purpose of salt.  Salt isn't a secret salt accomplishes two things.

1) Salt prevent precomputation attacks.  20,000 computer years is a long time right?  Well lets say your db is stolen today.  Well the strong passwords are safe for 20,000 years right?  What if attacker(s) started hashing passwords 20 years ago using 1,000 computers?  Without salt precomputation becomes a viable attacker.  Lookup tables for just about every algorithm would already exist and your password likely would be compromised before you even thought of it.   Even a password like "KJ#!Ks9d8k" would be instantly brute forced in "seconds" well technically not in seconds but the work can be done ahead of time so it would be compromised seconds after the db was compromised.

2) Salt prevents parallel attacks.  Say a password db has 10,000 records.  An attacker hashes password123.  Without salt they can compare it not against 1 record but against all 10,000.  1 hash = 10,000 attacks.  Ouch. With salt the hacker can hash password123 with the salt of record 1 but the resulting hash is only good for record 1.  To test "password123" against all 10,000 records requires 10,000 hashes.   Which is better security 1 hash = 10,000 attacks or 1 hash = 1 attack. 

Salt isn't a secret.  Salt is designed to limit the attacker to hash per attempted password per account in realtime.  Nothing more.
hero member
Activity: 784
Merit: 1009
firstbits:1MinerQ
August 16, 2012, 09:33:00 PM
#6
Actually I don't think that the algorithm is so important as limiting the # of attempts to login to the same account (as is done by banks) - it would be a pretty stupid piece of software that actually allows even 100 attempts to login to the same account within minutes.
Login count isn't relevant to cases where the password database is compromised - which is the only case that matters for GPU cracking as no one uses a GPU to login repeatedly.

What exactly do you mean by two factor?
Two factor has nothing to do with what you mention. It means two "modes" eg. something you know and something you have. Not two pieces of something you know as some people seem to think. There are many things that could qualify as something you have and a mobile phone is only one.

It should go without saying that a company that doesn't inform you up front that you need a phone to authenticate doesn't deserve to get your money to start with.

---
In my opinion password salts have limited usefulness if they are stored right next to the passwords. I say this because if you know the salt and how it's applied to the password then the work of the gpu finding the password is really just the work of scanning passwords. The salt is irrelevant since it takes so little time to calculate. I don't have a good solution off-hand for how to store salts separately or generate them as needed.

 

legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
August 16, 2012, 07:43:04 PM
#5
To anyone clinging to outdated ideas like using SHA-1 (or SHA-256/512, RIPEMD-160, etc) for storing passwords a simple question to ask yourself.  
Does your login server need to be able to process 4 billion logins per second?  No?  
Then why are you using a algorithm which allows the hacker to brute force at the rate of 4 billion attacks per second?  

Actually I don't think that the algorithm is so important as limiting the # of attempts to login to the same account (as is done by banks) - it would be a pretty stupid piece of software that actually allows even 100 attempts to login to the same account within minutes.
legendary
Activity: 2940
Merit: 1090
August 16, 2012, 07:35:36 PM
#4
A good outline of why website password schemes often fail to protect users and what developers can do to fix things.

For my Facebook account passwords are fine. 

When you are dealing with money, or at least any amount more than the cash you carry in your back pocket or purse, two-factor authentication should be mandatory.

What exactly do you mean by two factor?

Once upon a time I put some money into a forex site to set it to follow some "great trader"'s trades.

Once day I went to get my money back and could not because I have never had a mobile phone.

Eventually I could not even find that forex site anymore and still have not got that money back nor got a mobile phone.

So if by two factor authentication you mean hold people's money ransom blackmailing them to go get a device they have no desire to own, then I do not think it a good idea. I have no phone, I have no mobile phone, I have internet.

If by two factor you mean I should have to send them not only a PGP signed request but also some other form of signed request then maybe, but I expect a lot of people object to being required to learn to use PGP too...

Personally I am going with Open Transactions, but there too I see problems already, with various people complaining they will not use it until it has some kind of website method of using it, thus basically insisting the security be broken and the man in the middle people known as certificate authorities be given access to their funds. Weird but true.

-MarkM-
donator
Activity: 1218
Merit: 1079
Gerald Davis
August 16, 2012, 01:57:45 PM
#3


Nice find.  The use of "fast hash" algorithms for password hashing has been a pet peeve of mine for some time.  GPUs simply make the problem a couple magnitudes faster.  As OpenCL capable hardware makes it way into lower end computers expect botnets to gain a magnitude more hashing power per node.

To anyone clinging to outdated ideas like using SHA-1 (or SHA-256/512, RIPEMD-160, etc) for storing passwords a simple question to ask yourself.  
Does your login server need to be able to process 4 billion logins per second?  No?  
Then why are you using a algorithm which allows the hacker to brute force at the rate of 4 billion attacks per second?  

Use an algorithm like bcrypt and pick a workload so that your login throughput is only say 20 logins per second (@ 10% cpu load).   That means the average CPU based attacker can attempt couple hundred attacks per second, and the average GPU a mere couple thousand attacker per second.  
legendary
Activity: 2506
Merit: 1010
August 16, 2012, 01:41:34 PM
#2
A good outline of why website password schemes often fail to protect users and what developers can do to fix things.

For my Facebook account passwords are fine. 

When you are dealing with money, or at least any amount more than the cash you carry in your back pocket or purse, two-factor authentication should be mandatory.
sr. member
Activity: 252
Merit: 250
August 16, 2012, 09:43:16 AM
#1
http://www.troyhunt.com/2012/06/our-password-hashing-has-no-clothes.html

A good outline of why website password schemes often fail to protect users and what developers can do to fix things.

Quote
Let’s take a quick step back before talking about what’s wrong with the hashing algorithms of today. The problem that cryptographic storage of passwords is trying to address is to limit the potential damage of unintended disclosure of passwords in storage. Now of course all the good upstream security practices such as mitigating against SQL injection vulnerabilities and protecting your backups still apply, this is about what happens once things go really, really wrong.

It's a bit .NET-centric, but the lessons apply to any framework.
Jump to: