[WEB SECURITY] Idea: different approach to password hashing
jsteven at cigital.com
Mon Feb 3 15:04:04 EST 2014
Stalwart AppSec educator—thanks for the nod. Paul,
Your problem characterization is thoughtful, considering different forms of attack and the various surfaces upon which they can occur. You’ve even re-considered the (informal) threat model applying your proposed control alternatives. Well-played. Since you’ve taken the problem one or two steps past where most have, it’s worth following up beyond what I’ve posted publicly.
[Adaptive One-way Functions]
I would not oppose an approach predicated solely on an adaptive one-way function. Research load characteristics and tune for effective results.
> 1) Throw a lot of hardware at it. Lots.
You could throw iron at the problem (*1) using the standard adaptive one-way function formulations. Distributing the work from server to client is a natural response, yes, but not one I’ve seen in practice very often. You’re correct that doing so ‘inherits’ another problem: continued support for a user-specific salt (*2). You rightly indicate that it also inherits the problem of obscured credential replay by MitM.
In essence, this design leads down a slippery slope to a home-rolled challenges/response (C/R) protocol—something to be avoided. We see Existing C/R schemes, such as OAuth, protect plaintext credentials against MitM theft. Bearer tokens (application/end-point ‘passwords') used by these schemes can help designers limit the amount of CPU-intensive server-based credential verification. When designing systems, prefer these to home-rolled schemes; their limitations are well-understood (*3).
> 3) Use a [server-side] HMAC, … [and do it well]
I would suggest this approach and advise carefully solving knock-on problems.
As stated, I’m a fan of this approach, principally because it is both simple and because it forces the attacker into asymmetric (disadvantaged) warfare with the defender (*5). That is, the defender is subject to only nominal password verification effort whereas the attacker must pay to brute force (or steal) the secret key prior to enjoying the same ease of verification.
As Jim hedged, one inherits the ‘key protection’ problem with this scheme. Detractors rightly indicate organizations can easily screw key protection up. Within my own experience, it’s been easy to design solutions because the organizations with which I work enjoy benefits like a) separate of duties involved in generating, handling, and using key material, b) reasonable application server configuration, and c) broadly deployed HSM support. Though, even without fancy hardware, organizations often have existing regimes for production secret protection.
[Paul’s Proposed Design]
Paul, the approach you proposed (*6), as I understand it, may be represented as follows:
(0) Client C: uname —> Server S
(1) S: SHA2(server_salt + uname) —> C
(2) C: bcrypt(salt, pw) —> S
(3) S: verify(SHA2(<bcrypt result>))
My “brief” analysis of this approach places it (surprisingly?) in an equivalence class with bcrypt itself, once known to an attacker. For those interested in why, contact me offline.
This scheme does provide some additional protections to credentials in flight (during step (2)). if designers desire this effect, I’d recommend revisiting the C/R section and selecting from that family of approach.
+1,703-727-4034 | @M1splacedsoul
* (1) - http://www.youtube.com/watch?v=8mbkWMEMB9s
* (2) - Some ascribe anti-reversing properties to salts beyond obscuring duplicate plaintext and raising space/time difficulty on targeted individual attack. This results in complaint about salts made public.
* (3) - http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/
* (4) - https://github.com/symeapp/srp-client
* (5) - http://goo.gl/Spvzs
* (6) - Quoted from Paul’s mail:
>> 1) The salt can be generated as hash(server_salt + user_name) - where server_salt is a random number that is unique to the server, public, and the same for all users. The resulting hash appears to have the required properties of a salt.
>> 2) The server should do a single, fast, hash operation on the hash it receives. As an example: the server stores SHA-256(bcrypt(salt, password)). The client sends bcrypt(password) then the server applies SHA-256 and checks the hash.
> John Stevens
More information about the websecurity