Leszek, On Thu, May 7, 2015 at 2:11 AM, Leszek Krupinski <leafn...@gmail.com> wrote: > On Wed, May 6, 2015 at 4:00 PM, Nikita Popov <nikita....@gmail.com> wrote: > >> It should be further noted that there is no standardized crypt() format for >> PBKDF2 and password_hash() is a crypt-compatible API. As such supporting >> PBKDF2 there would be very problematic. We do already support it in the >> form of hash_pbkdf2() and people who wish to use this method (e.g. due to >> legal restrictions) can use it through this API - I don't see a reason to >> have it in password_hash(), which should only support the recommended >> default use case. >> <http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf> >> > > That's true that there's no support for pbkdf2 in crypt. On the other hand, > the RFC for password_hash stated: > >> These hashing APIs will initially be thin wrappers around *crypt()* to > allow for automatic salt generation and better error checking. > > It says "initially" - that's why I understood that in the future we can > diverge from crypt in situations when there's a great new hash we would > like to use, but it's not supported by crypt (yet or at all).
That was precisely the intention. For that exact reason. *HOWEVER* (and this is a big however), I think we should avoid doing that unless *absolutely* necessary. We should strive to build off standardized crypto. This is good both from an interoperability standpoint, and the standpoint of relying on cryptographers to set the standard. We have few if any professional cryptographers on this list/project, so we should avoid as much as possible inventing our own (unless absolutely necessary, in which we can elicit the help of professionals). > Also, I'm pro-choice ;) We have an extensible API for password_hash(), and > because people have different needs (like gpu strain in bcrypt or longer > passwords in pbdkf2) we should provide an option for more experienced > users, while having reasonable defaults. Yes, advanced users can use hash > functions directly, but password_* are so nice :) Well, I'm not sure I agree here. I think the point of password_hash() is to raise the bottom barrier. I have said multiple times that it is not a replacement for crypt(3) or other more complicated tools. It's meant more as a way for non-experts to implement secure code. If you need to make a different tradeoff, then you can always use a different library or more advanced use case. I think that password_hash() should remain simple, with as few choices as possible (less for users to screw up). As far as length protection, you can simply pre-hash with sha-512 and base64_encode the result: $prehash = base64_encode(hash('sha512', $password, true)); $hash = password_hash($prehash, PASSWORD_DEFAULT, []); This is also "inventing" crypto, so I would be extremely wary of recommending this as a project. If we can get the upstream providers (specifically the OpenBSD project) to add a crypt(3) format for this specific case, then we can integrate it into our crypt(3) implementation, and hence password_hash(). But I would want the upstream to do it first. The only algorithm at present that I have seen that today could replace bcrypt in password_hash is scrypt. However, there are 2 fundamental problems with it: 1) there's no crypt(3) binding or format. 2) At similar cost settings to what most users use bcrypt at (< 0.1 second runtime), it's been shown to be at best no stronger than bcrypt, or at worst several times weaker. There is currently a competition for a new password hashing algorithm: https://password-hashing.net/ I've been watching it fairly closely, but many of the algorithms suffer a similar "weaker than bcrypt at low runtime" problem. The main reason for this is that they are mainly targeting different use-cases than password_hash targets. Namely, they are looking at key derivation and login where you can dedicate a login server (and hence keep potentially GB of memory persistent for use in hashing). While these techniques are far superior if you can dedicate the hardware to them, they don't solve the same problem that we're solving with password_hash. We could use scrypt or yescrypt (or a few others) as a next-gen algorithm, but we'd have to be careful with the settings parameters, as there's more than just one. And it's really easy to screw up the settings and make it easier for an attacker. Ideally, I wonder if it's possible for us to simply "proxy" from a single setting (give users a "cost" setting, and generate an pseudo-ideal set of settings given that cost). The bottom line is that I think password_hash needs to stay as simple as possible. It's not designed to be a full fledged library or set of primitives. It's designed to be an opinionated library that takes as much decision away from the user as possible. If you need more control, use a different library. But for the 98% use-case, that additional complication simply makes it harder for users to get it right: http://blog.ircmaxell.com/2015/03/thoughts-on-design-of-apis.html Anthony -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php