6 ms·
Creating and Verifying Hashes in PHP 5.5
- jimwalsh 13y agoThanks for easily explaining this for everyone.
- pmtarantino 13y agoIf you are using a PHP < 5.5, use this library: https://github.com/ircmaxell/password_compat https://github.com/ircmaxell/password_compat
- chrisguitarguy 13y agoThere's also a library for PHP >= 5.3.7 that provides the same API if PHP 5.5 isn't an option yet. https://github.com/ircmaxell/password_compat https://github.com/ircmaxell/password_compat Written by Anthony Ferrara, the same guy behind the `password_*` API in PHP 5.5
- fein 13y agoThere's also PHPass from OpenWall: http://www.openwall.com/phpass/ http://www.openwall.com/phpass/
- kijin 13y agoIf you use PHPass, remember to check your hashes to make sure they're actually hashed with bcrypt. PHPass falls back to a less secure algorithm if bcrypt is not available in your PHP version. Most of the CMS's that claim to use PHPass actually use the "portable" option, which is based on MD5, because they want to remain compatible with PHP versions lower than 5.3 (the first version that is guaranteed to support bcrypt).
- chrisguitarguy 13y ago> Most of the CMS's that claim to use PHPass actually use the "portable" option This is true for WordPress, which uses PHPass. You have to replace `wp_hash_password` to get WP to use bcrypt: http://wptip.me/wordpress-bcrypt http://wptip.me/wordpress-bcrypt
- bpatrianakos 13y agoThis is a great addition to PHP. Before, most new devs would either skip hashing passwords altogether or use `md5()` or `sha1()`. So you'd end up with databases with passwords in plaintext or easily cracked. Bcrypt frameworks for PHP were too confusing for beginners. If you were lucky you were using a framework that took care of hashing and salting passwords and if you were extremely lucky you had bcrypt available on your PHP install and that framework used it. But that didn't always happen. There do exist experienced PHP devs who would do password storage the right way but PHP up until now neither made it easy nor encourage these practices as they relate to passwords. Now I hope word gets out about this and people stop using md5() thinking their passwords are safe. Not that md5 is necessarily bad, but most people don't realize there are better tools for maintaining secure passwords. Also, this reminds me a little bit of `has_secure_password` method in Rails minus some of the automation that comes with it.
- andyhmltn 13y agoI remember using BCrypt in PHP a few years ago. It was the first time I'd ever used BCrypt but it wasn't easy to find any resources on using it with PHP. Well at least not in the correct way.
- tstactplsignore 13y ago>There do exist experienced PHP devs who would do password storage the right way but PHP up until now neither made it easy nor encourage these practices as they relate to passwords. I'm happy to be one of them! The app I'm currently building uses this bcrypt library, and I can only highly recommend it: http://www.openwall.com/phpass/ http://www.openwall.com/phpass/
- bpatrianakos 13y agophpass is actually one of the libraries I was talking about. When I first encountered it I was really intimidated. The usage didn't seem that bad to figure out but trying to comb through it's page to find installation instructions was tough. It didn't seem clear about whether this was a module like imagemagick that needed to be installed or if it was a drop-in library you could just use within any project. Looking back now it seems obvious but back then it just too overwhelming. With PHP there's this 'just get it done' attitude and futzing around with phpass wasn't something I could let myself do back then. Of course I now regret it. I ended up using a different encryption library for password storage on my app. It isn't md5 but I know it could and should be stronger. So now I'm in a situation where I'm rewriting the codebase in a different language entirely and the cherry on top is that I need to migrate all my user's passwords and even some data from the original method to bcrypt, which I'm now using. It seems simple in theory but I have a feeling this is going to cause some headaches. However, its totally necessary and especially for the type of application I'm working on which puts a big focus on privacy and security.
- deleted 13y ago[deleted]
- showerst 13y agoJust noting if you're new to this you don't have to add a salt, by default password_hash with bcrypt will add a random one to each password.
- nly 13y agoAssuming the RNG isn't duff, which PHP has stumbled on a few times in the past, with session keys and such.
- ircmaxell 13y agoCheck it out for yourself. Here's the random generating parts, pulled out for you: http://stackoverflow.com/questions/14673005/how-does-phps-password-hash-generate-the-salt http://stackoverflow.com/questions/14673005/how-does-phps-pa...
- lukeschlather 13y agoHow does that work? Don't you need the original salt to verify the hash?
- eterm 13y agoThe salt is stored in the hash itself, so it can extract the salt from any provided hash. (Neat huh?)
- pjscott 13y agoHere's a quick explanation of the format, in case anybody's interested: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html#format-algorithm http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html...
- masklinn 13y ago> 'salt' => password_hash("MySalt",PASSWORD_BCRYPT)] This is really, really dumb and pointless. In fact it makes absolutely no sense, it tells password_hash to use a bcrypted "MySalt" as a salt. Not only is there no reason to explicitly provide a salt unless you already have bcrypted passwords in a non-standard format, (in which case you'd pass the existing $salt directly, you wouldn't bcrypt it) this is an inane way to generate one. If you want to generate your salt by hand, don't do it. If you really, really, really want to, use mcrypt_create_iv.
- Jeremy1026 13y agoNoted, and edited. Thanks for the suggestion.
- Kudos 13y agoYou should have removed the salt entirely, after all the article is supposed to be "The easy way". Edit: also the default cost is already 10, you should offer the $options as an aside and not suggest using them as standard practice.
- bpatrianakos 13y agoAdding that salt is optional. I'm pretty sure the author just added it to the post so people know it exists. I don't think it's dumb and pointless at all, really. Generally you wouldn't generate a salt yourself if you're using bcrypt however I'm sure there would be cases where it would be needed or even preferred for some reason. I would advocate for flexibility and education rather than rigidity and simplicity. That is to say, rather than make the function useless to those who'd need their own salt I think it's a better idea to allow these options while making sure developers know that they should only be used in certain situations. A function like this isn't bad because it can be misused.
- masklinn 13y ago> Adding that salt is optional. I'm pretty sure the author just added it to the post so people know it exists. I have nothing against adding a salt manually to show how it works, I have things against adding stupid salts. > I don't think it's dumb and pointless at all, really. You're missing the criticism. The problem isn't the ability to inject a salt (it is useful e.g. when the (cost, salt, hash) triple is in a format other than MCF), it is the way the salt is obtained.
- deleted 13y ago[deleted]
- baby 13y agoCan someone explain to me what the "cost" option is?
- Jeremy1026 13y agoThe cost option is how algorithmically complex the resulting hash will be. The greater the cost, the longer it takes to create the final hash, but the more secure it is. Lower cost = lower secure. Basically you want to use as high of a cost as you can on your servers hardware, without producing a noticeable slowdown to the end user.
- cabirum 13y agoIncreasing cost by 1 doubles the time needed to create a hash. A simple benchmark with results: http://pastebin.com/NiqKEAVm http://pastebin.com/NiqKEAVm
- mikeryan 13y agoOne reason why Bcrypt has taken over for other hashing algorithms is because it introduces a "work" factor which allows you to extend the amount of time it takes to calculate the hash in order to prevent brute force attacks. By making the work factor or "cost" adjustable you get some protection against Moore's law because as computers get faster you can up the "cost". Canonical article on why bcrypt which explains it here http://codahale.com/how-to-safely-store-a-password/ http://codahale.com/how-to-safely-store-a-password/
- workhere-io 13y agoIt certainly makes handling passwords easier. Another option, though, would be to use Persona, in which case you don't store passwords at all.
- cryptbe 13y agoIf the password hashing APIs asks developers to generate a salt on their own it's neither easy nor safe. I've worked on password hashing recently, and I think the best interfaces should take only a password, and return a hash. Modern password hashing algorithms, e.g., bcrypt, scrypt, etc., usually also need a set of local parameters. The API should hide them as well, and expose only a set of interfaces with safe and sound preconfigured parameters, which in turn determine how much CPU time and memory space will be used. One disadvantage of this approach is that it exposes the local parameters, hence make it a little bit easier for attackers. This is exactly how crypto primitives have been designed. If the designers of AES ever let people choose the key size, sooner or later some people would shoot themselves in the foot, and set the key size to 1-bit. If you think this is an extreme example, it actually has happened, not in some obscure API that nobody uses, but in the very XMLDsig standard published by W3C [1]. Regarding password hashing standards, I found many misuses of libscrypt that would make it extremely easy to recover passwords. But I'll save the details for another blog post or something. [1] http://www.w3.org/QA/2009/07/hmac_truncation_in_xml_signatu.html http://www.w3.org/QA/2009/07/hmac_truncation_in_xml_signatu....
- chunsaker 13y agoThis is an awesome improvement. I agree with BPatrianakos that hashing has not been easy enough for the average PHP dev - we hear that a lot. As another option, you can also just not build any password infrastructure. We do all the hashing and authorization as a secure service and there are PHP devs of all levels using it... http://www.stormpath.com/docs/php/quickstart http://www.stormpath.com/docs/php/quickstart