hasgeek / lastuser

Lastuser has been merged into Funnel. This repository is archived.
https://hasgeek.com/
BSD 2-Clause "Simplified" License
166 stars 30 forks source link

Use bcrypt/scrypt for client credentials #234

Open jace opened 6 years ago

jace commented 6 years ago

Since #69 we've used SHA256 for client credentials. The rationale offered in b000a5057a65fc5eff146ffde6c9a7968e020616 and 8d361caeed4f70766eee09f0f8607a0a361dc366 (in January 2015):

We use unsalted SHA256 instead of a salted hash or a more secure hash like bcrypt because:

  1. Secrets are UUID-based and guaranteed unique before hashing. Salting is only beneficial when the source values are the same.
  2. Unlike user passwords, client secrets are used often, up to many times per minute. The hash needs to be fast (MD5 or SHA) and reasonably safe from collision attacks (eliminating MD5, SHA0 and SHA1). SHA256 is the fastest available candidate meeting this criteria.
  3. We are stepping up from an industry standard of plain text client secrets, not stepping down from stronger hashing.
  4. To allow for a different hash to be used in future, hashes are stored prefixed with 'sha256$'.

This rationale was written at a time when HasGeek code did not make extensive use of cache. Adding a cache layer can solve for this:

  1. The ClientCredential model stores salted bcrypt or scrypt.
  2. Lastuser receives a credential in plain text over HTTPS.
  3. Lastuser looks for a cached credential, and if one exists, computes an SHA256 hash to match with cache. The cache does not hold plain text.
  4. If not cached, Lastuser encrypts using bcrypt/scrypt to compare with the stored credential.
  5. If the stored credential matches, an SHA256 cache entry is created for one hour/day/week (depending on estimated frequency of usage).

Why bother with this switch to bcrypt/scrypt if SHA256 is good enough? Because databases do get hacked, and application passwords control access to the data of multiple users, not just one.