9 ms·
The new Secure Password Hashing API in PHP 5.5
- titraxx 14y agoI think http://crackstation.net/hashing-security.htm http://crackstation.net/hashing-security.htm is better.
- deleted 14y ago[deleted]
- mylittlepony 14y agoHave you even read that? It recommends bcrypt too: http://crackstation.net/hashing-security.htm#faq http://crackstation.net/hashing-security.htm#faq
- titraxx 14y agoOups, my mistake. I thought that md5 was used by default by the new API (I made a quick read) but you are all right ! Tiredness can be deceptive... But it's still a good website where I learned to make secure password hashing for the first time.
- Kudos 14y agoA standard API with sane defaults is an excellent idea for a language with so many developers of varying competencies.
- romaniv 14y agoConsidering that this will make password-related code much shorter and more readable, I think it's a good idea regardless of what level of competence you expect from the developers.
- underdown 14y agoI'll take "more secure" over short and readable any day.
- Kudos 14y agoIn some cases short and readable ends up as "more secure" by virtue of being implemented correctly.
- ErrantX 14y agoOr in this case; short and readable is more secure because attack vectors, like generation of salts, are wrapped inside the new API.
- regularfry 14y agoThere are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. - C. A. R. Hoare
- FuzzyDunlop 14y agoIndeed. Of course all the sane defaults in the world won't stop someone copying and pasting shit like this from a dodgy tutorial: $password = mysql_query("SELECT password FROM users WHERE email = ".$_POST['email']." LIMIT 1"); To clarify this to the downvoters who chose not to comment: The finest password hashing algorithm ever committed to source control won't protect your other sensitive information (address, phone numbers, etc.) when SQL injection can make your entire database vulnerable to attack.
- Kudos 14y agoYes, but there's a greater chance that basic tutorials that for example use unsalted sha1 will use this method instead. It's just as simple for a beginner to grok, but secure by default.
- ErrantX 14y agoThe code he posted has different vulnerability; i.e. SQL injection. Your password could be ultra-secure, but it doesn't matter if you use that code without sanitizing inputs :) I guess the reason he is being downvoted is; badly hashed passwords are not merely a newbie problem...
- Kudos 14y agoSQLi a different though related issue so I reframed it with an example that this solves.
- tlrobinson 14y agoI'd say it's an excellent idea for every language.
- Kudos 14y agoI agree, so much so that I started working on something for Python after seeing this.
- tptacek 14y agoDefaults to bcrypt with a cost factor of 10. A totally sane default. The interface is clear, simple, and easy to audit for. This is a definite step forward.
- 16s 14y agoAuditing bcrypt (OpenBSD Blowfish) hashed passwords with JtR is much less satisfying than auditing md5 hashed passwords ;) Joking aside, I agree that this is a good move in the right direction.
- tptacek 14y agoYeah, I'm just saying, the new standard password hash has a simple function signature; it's now easy to take a new PHP codebase and quickly check it to see if they're doing something wacky with passwords.
- stouset 14y agoRead the comments. Users are already questioning these totally sane decisions and asking about ways to circumvent it.
- gthank 14y agoIt's PHP. They obviously wanted a broken language. Now the devs are taking that away from them.
- davedx 14y agoLooks very similar to the API in Laravel. [1] I'm always happy to see PHP moving forwards like this. Baby steps towards better practices! http://laravel.com/docs/auth/usage#hash http://laravel.com/docs/auth/usage#hash
- joelthelion 14y agoPlus the salt seems to be concatenated in the hash. Very cool and user friendly.
- 14y ago
- onethumb 14y agoSeems bizarre to me that hash_pbkdf2() has also been accepted, was authored by the same author, and provides for "better"* hashing than bcrypt(), and yet isn't the PASSWORD_DEFAULT or, indeed, even an option for the secure password hashing algorithm. wtf? * In the crypto community, "better" usually refers to how long an algorithm has been around, how well reviewed & used it is, and how bug-free it's been. Looking at all of these, PBKDF2 is clearly superior to bcrypt, which has had significant bugs, isn't as widely deployed, etc. https://wiki.php.net/rfc/hash_pbkdf2 https://wiki.php.net/rfc/hash_pbkdf2 http://en.wikipedia.org/wiki/PBKDF2 http://en.wikipedia.org/wiki/PBKDF2
- JoachimSchipper 14y ago[EDIT: tptacek is right. Listen to tptacek.] PBKDF2 isn't necessarily better than bcrypt. But yes, it's a good choice.
- tptacek 14y agoPBKDF2 is objectively worse than bcrypt, but the difference between them isn't meaningful. The only meaningful choice in password hashes is between PBKDF2/bcrypt and scrypt, which is hardened against gate-level-optimized attacks.
- pbsd 14y agoThey're not comparable: PBKDF2 is a mode of operation, bcrypt is an actual instantiation of a password hashing scheme. Saying one is (objectively) better than the other is meaningless, or at least very misleading.
- tptacek 14y agoNone of what you've said about PBKDF2 vs. bcrypt is true. PBKDF2 is inferior to bcrypt (see Colin's scrypt paper for details), has never had a published design flaw, and is less widely deployed than PBKDF2 (many people think they're "doing PBKDF2" when they iterate a hash function 1000 times). Having said all that, who cares? Pick one or the other. I'd have exactly the same positive comment regarding the new PHP interface if they had used PBKDF2 with a sane cost. The only harmful decision you can make regarding password hashes is to wait to implement them in order to pick the "best" one.
- nthitz 14y agoSo you are supposed to md5 the results of the password_hash() function before storing them in a database right?
- martin-adams 14y agoOf course! It totally adds another layer of protection :)
- deleted 14y ago[deleted]
- mikle 14y agoDon't forget double rot13.
- 16s 14y agoFor those who may not get this joke: # One rot13 $ echo test | wm --rot13 --words stdin grfg # Double rot13 $ echo test | wm --rot13 --words stdin | wm --rot13 --words stdin test
- 1SaltwaterC 14y agoIt's actually called ROT26: "An encryption scheme similar to ROT13, but twice as secure."
- mparlane 14y agoIf this was NOT a joke... No, do not md5 as you will lose hash type info. edit: To be clear I am assuming it IS a joke. I hope.. oh god I hope.
- Dylan16807 14y agoWhy would you even worry about it not being a joke? Even if by some quirk of fate they were serious, the code would immediately fail and put no data at risk.
- 14y ago
- leftnode 14y agoThis is a great step forward. I wish it was in an object rather than globally scoped methods, but it's nice to have. Also, in case you didn't know, you can use bcrypt with PHP5.3 and the crypt() function. It's not as user friendly as this, but you can do it.
- ircmaxell 14y agoHere's an explanation of my rationale for not making it an object instead of a function: http://www.reddit.com/r/PHP/comments/zrprk/the_new_secure_password_hashing_api_in_php_55/c677yu2 http://www.reddit.com/r/PHP/comments/zrprk/the_new_secure_pa... Here's the last paragraph (in case it's TLDR, or you don't want to click through): > So in short (or not), I just felt that there's room for this API and things like PasswordLib to live side by side. And I will continue to maintain that project in the long run. But for the generic use-case, I felt that an OOP API was too much risk for not enough gain for a core implementation. With that said, if you can come up with a clean API, I'd be all ears and willing to consider implementing it. But for now, this is the better alternative IMHO...
- pwaring 14y agoOr you can use this library: http://www.openwall.com/phpass/ http://www.openwall.com/phpass/ It does all the work for you, and will even fall back to other algorithms if you don't have bcrypt available.
- RossM 14y agoFor clarity, the current and new ways to use bcrypt in PHP: // pre-5.5 $salt = substr(strtr(base64_encode(openssl_random_pseudo_bytes(16)), ['+' => '.']), 0, 22); $hash = crypt($password, '$2a$10$'.$salt); $match = crypt($password, $hash) == $hash; // post-5.5 $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 10]); $match = password_verify($password, $hash); Brilliant effort and should really help to ensure password security on the web.
- nikic 14y agoJust to clarify a bit more: Usually you need more (a lot more) code than this on pre 5.5. In particular you can't normally assume that `openssl_random_pseudo_bytes` is available. Instead you'll go through various entropy sources (typically `mcrypt_create_iv`, `/dev/urandom`, maybe COM, with fallback to `mt_rand`). People often get the salt generation wrong, e.g. by just using a substring of `md5(mt_rand())`, which is obviously wrong (in several respects) :/
- TazeTSchnitzel 14y ago>People often get the salt generation wrong Yep. Can't wait for GoogleGuy's php-doc changes to get in, then I could downvote suggestions like this: http://www.php.net/manual/en/function.hash.php#101987 http://www.php.net/manual/en/function.hash.php#101987
- notJim 14y ago> obviously wrong (in several respects) What are the ways this is wrong? I know that mt_rand is not a cryptographically secure RNG, but what are the other ones? (NB: I do not write my own auth/password code.)
- AgentConundrum 14y agoI know this is a dumb question, but I haven't found a great answer to it yet: why does it matter how the salt is generated, so long as its done on a per-user basis? If the salt is allowed to be "less than secret" (by which I mean it can be stored in plain-text, not that it should be published on your website), then what does it matter if it's "pretty random" versus "cryptographically random"? What's wrong with something like this: $salt_length = 22; $cost_factor = 10; $lower = range('a', 'z'); $upper = range('A', 'Z'); $numeric = range('0', '9'); $special = array('/', '.'); $salt_chars = array_merge( $lower, $upper, $numeric, $special ); $char_count = count($salt_chars); $salt = ''; for ($i = 0; $i < $salt_length; $i++) { $salt += $salt_chars[mt_rand(0, $char_count -1)]; } $hash = crypt( $password, '$2a$' . $cost_factor . '$' . $salt );
- 16s 14y agoDuring the Defcon password cracking contest this year, there were 5,150 bcrypt hashes. In 48 hours, only 76 of them were cracked. In contrast, there were 8,544 plain sha1 hashes, 4,111 of those were cracked. You can see the full list of hash types and how many were cracked here: http://contest-2012.korelogic.com/stats.html http://contest-2012.korelogic.com/stats.html This is probably the premier password cracking contest in the world. I placed 7th overall and was first to crack most of the TrueCrypt volumes and I despise attempting to crack bcrypt hashes (most sane people do). You really have to try and crack them for yourself to fully appreciate how difficult and slow they are to attack.
- JakeSc 14y agoWere most people using rainbow tables or brute forcing do crack the hashes?
- baudehlo 14y agoThe point of bcrypt is you can't use a rainbow table.
- tptacek 14y agoNo modern hash function, including "salted SHA" and Unix crypt() is vulnerable to "rainbow tables". Rainbow tables work exclusively against the dumbest possible hashing schemes. Bcrypt isn't a defense against "rainbow tables"; the hash function bcrypt supplanted (PHK's MD5 crypt) was also not "rainbow-table-able".
- ZoFreX 14y agoCorrect me if I'm wrong but couldn't you construct rainbow tables for any hash function which takes a single input (including salted SHA, if the salt is the same for all passwords)? Of course, you'd need a seriously large set of passwords on your hands for it to be worth the effort, but it could be done right? (Possibly worth mentioning, possibly not, that if your salts are extremely weak then the combined hash might show up in regular rainbow tables, whether your salts are unique or not - it seems unlikely this would ever happen in practice though)
- 16s 14y agoIs this officially part pf PHP 5.5 or just an RFC that might be included in PHP 5.5?
- nikic 14y agoThe RFC was accepted. So it will be in PHP 5.5 (unless some serious flaw with it comes to light in the meantime).
- mvts 14y agoWow, that actually is very useful. Looking forward to using it.
- acabal 14y agoVery nice. I'm surprised, though, that they didn't go the OOP route, since they're transitioning a lot of other core procedural functions to objects. Even if it would be a super-simple class interface (almost to the point of not being strictly necessary), it would at least be consistent with the general drift of next-gen PHP.
- chrismsnz 14y agoI think the PHP's standard library is as inconsistent as the next guy, but I kind of appreciate there just being a function when just a function is needed. i.e. Python's standard library provides objects where appropriate, but often they will just put functions directly into modules for simplicity.
- ircmaxell 14y agoI wanted to go down the OOP route initially. Then I decided against it for a number of reasons. Here's a breakdown of that reasoning... http://www.reddit.com/r/PHP/comments/zrprk/the_new_secure_password_hashing_api_in_php_55/c677yu2 http://www.reddit.com/r/PHP/comments/zrprk/the_new_secure_pa... Additionally, the general drift hasn't been towards OOP within PHP. Some OOP libraries are being added, but the core remains largely procedural (and doesn't appear to be shifting significantly yet). It's taking the (very logical IMHO) route of "Does this make sense to be OOP". If the answer is yes, then it goes in as a class structure. If not, it goes in procedurally. I did not feel it made sense to make this a class, and as such I did not...
- verisimilitude 14y agoI was using Marco Arment's class Bcrypt before: https://gist.github.com/1053158 https://gist.github.com/1053158 This is a nice improvement.
- DigitalSea 14y agoThis is great news. One of the things that PHP has been lacking for some time is easy to use secure password hashing. You'll still have instances where developers are either too lazy, forget or don't learn these new methods and the same problems will occur. It's great to see the PHP team thinking ahead, and I completely understand and agree with why they chose procedural over an object oriented approach to implementing the new functionality: ease of use. Next step I hope is some kind of native support for web sockets, I'm tired of using third party libraries that don't implement a web socket server correctly. That would be an amazing feature.
- astrodust 14y agoAs much as the PHP team is thinking ahead and working hard, there's a ton of inertia in the PHP community that will take another decade to overcome. The one thing that would help the PHP community immensely is nuking w3schools from orbit. It's like a museum of bad ideas that somehow is the first place people end up when looking to learn PHP.