[OWASP-Security101] Security101 Digest, Vol 2, Issue 4
michael.coates at owasp.org
Thu Mar 15 20:20:56 UTC 2012
Here's my overview on the purpose and value of each part of password hashing :
* Hashing: 1 way operation that prevents an individual from recovering the password from the hash value (minus brute force concerns)
* Per User Salt: Goal is to minimize effectiveness of time-memory tradeoff attacks (e.g. rainbow tables). Also eliminates being able to look at the password hashes and easily see what users have the same password (since the hashes would be the same)
* Salt Storage Location: Irrelevant - The point of a salt is to eliminate use of rainbow tables. The salt is not a secret value. Even if the attacker gets the salt they'd still have to build the rainbow table from scratch for each user. That is a ridiculous amount of time
* Hash Iterations (e.g. bcrypt): Makes brute forcing a hash value incredibly time consuming to the point where it is unreasonable for passwords that are not incredibly simple
* System Nonce: A secret value stored outside of the database that is added into the password hashing process (like a salt). This increases password entropy for offline attacks assuming the nonce is not disclosed with the hashes.
The system nonce idea isn't talked about as much. But it's an idea I like. The theory is that you store this value on the file system and use a call to that file to retrieve the nonce during the password hashing process. If an attacker discovers an SQL injection and dumps your password hashes they won't get the system nonce so its not in the database - its on the file system. Now, if they fully root the box they'll of course get this value, but you're in no worse situation then before (i.e. when you didn't use a system nonce)
Dinis, to your specific question, you control the time (aka cost). So you can increment the password verification process by 1/10 of a second or whatever you want. The impact to the user is negligible, but the benefits to slowly down offline attacks is huge.
Michael Coates | OWASP
michael.coates at owasp.org | @_mwc
On Mar 14, 2012, at 5:05 PM, dinis cruz wrote:
> I have this 'how to store passwords' problem at the moment with the
> TeamMentor (TM) product I'm working on. I current store the password
> hashes in a file (XML since TM doesn't use a database) and I have no
> 'secure' place to store a secret or Salt(s)
> Add to the mix that this hash is also calculated on the client side so
> that when using Http the clear text password is not sent over the
> I'm not convinced that per-user hash adds a lot more that we have
> already, but I like the idea to introduce a more expensive hashing
> process. That said , is that really that effective and practical? (I
> really don't want a password verification process that takes too long
> to execute)
> Dinis Cruz
> On 14 Mar 2012, at 16:55, Michael Coates <michael.coates at owasp.org> wrote:
>> On Mar 13, 2012, at 6:59 PM, Bill Sempf wrote:
>>> On Tue, Mar 13, 2012 at 8:35 PM, <security101-request at lists.owasp.org> wrote:
>>>> Yes, its good to adhere to best security practices at all times. Understanding the full threat model and risks throughout the system also help prioritize where security improvements should be spent. For instance, we certainly shouldn't send passwords over email, but as we see from all systems, password resets are often sent over email. The difference is that these are single use tokens with rapid expiration times, but it still points to the larger issue that it's tough to build a secure communication if we're all over unencrypted email.
>>> My problem is that if MailMan sends the email in plaintext, it stores
>>> it in plaintext. Now, I remember that from my Unix Admin days, but
>>> that was back in 1992. Surely there is a better way these days.
>> Yes, I haven't personally dug into the internals of mailman, but if any website sends you your clear text password they are doing 1 of 2 things:
>> 1. Storing the password in a database in the clear
>> 2. Storing the password using symmetric encryption with the key accessible to the application for decryption
>> In case 1, a SQL injection that provides access to the database provides the attacker with all clear text passwords for all users. Very bad.
>> In case 2, a SQL injection on its own would give the attacker encrypted passwords. If they key was also stored somewhere in the db then the attacker could just grab this value and decrypt the passwords on his device. Also very bad. Even if the key is stored outside the db on the file system, this approach is still really a bad idea since its so easy for an admin or rogue employee to get at the passwords.
>> To keep things in perspective - this is a mailing list and the random password for mailman helps prevent others from unsubscribing you. Not a ton of risk and just use a unique value provided by the mailing software
>> But, diving into the larger issue - What is the best way to do password storage?
>> Password hashing - But not just password hashing on its own. You need to use a per user salt and a hashing method that is not fast (e.g. iterate the hash). That second part is often missed during design. The important part about iterating the hash is to introduce an element of work (e.g. time). By introduces a small amount of work to verify a password you increase the relative amount of time to check one password by a small percentage, but increase the overall amount of time to brute force an entire range of passwords by a very large value.
>> More reading here:
>> I recommend checking out bcrypt or scrypt specifically to find out more on password iterations:
>> Michael Coates | OWASP
>> michael.coates at owasp.org | @_mwc
>> Security101 mailing list
More information about the Security101