psecio / gatekeeper

Gatekeeper: An Authentication & Authorization Library
366 stars 23 forks source link

Tokens should be stored as securely as passwords #41

Closed fredemmott closed 8 years ago

fredemmott commented 8 years ago

A token allows you to log in as a user, so should be considered largely equivalent to a password (though they don't have the reuse issue). Why are they stored with a simple hash instead of bcrypt/scrypt/pbkdf2?

enygma commented 8 years ago

@fredemmott Good point - they probably should even though they're from a randomly generated value. It wouldn't change the external interface for it either, so always a plus. Feel up to a PR?

fredemmott commented 8 years ago

Sorry, that's unlikely - I don't use this, I just read a blog post that apparently matches this (https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence) and thought this would be the most constructive thing I could do :)

enygma commented 8 years ago

No worries - figured I'd ask though :) I appreciate the feedback!

paragonie-scott commented 8 years ago

The reason that passwords are hashed with bcrypt/scrypt/PBKDF2 is that they are designed to take human provided inputs (notoriously low entropy values) and make it expensive to brute force the values.

For reference, if a typical password has 50 bits of entropy, it might take 2 hours to brute force its MD5 hash. By comparison, it would take centuries if it was hashed with bcrypt.

Adding a key stretching to the storage for a 256-bit value provided by a CSPRNG isn't necessary. The purpose of a hash is so that someone with the token hash (which shouldn't ever be leaked; this is defense-in-depth) can't simply set their cookie to the token and impersonate the user. Adding slow-hashing to this value just makes your application slower.

Brute-forcing a 256-bit token is not going to happen, even with a fast hash like SHA256.

https://www.reddit.com/r/theydidthemath/comments/1x50xl/time_and_energy_required_to_bruteforce_a_aes256/

fredemmott commented 8 years ago

Thanks, that makes sense.

paragonie-scott commented 8 years ago

Any time. :)

For reference, my first draft of that blog post used bcrypt, but it was controversial for exactly the reasons I reiterated above and I couldn't really justify using it. (My only rational motivation was for 5.5 compatibility, where hash_equals() wasn't available yet.)