DEV Community

Discussion on: PHP Security: Passwords

Collapse
 
tadman profile image
Scott Tadman

While there’s some good ideas here, this all sounds like a really bad idea. Bcrypt does a really good job and can be tuned to be even harder to crack, making it very good at resisting brute force dictionary attacks. There’s other similar algorithms that can be better, but Bcrypt is a good baseline.

This HMAC approach, even using SHA3, seems really high risk, and the AES layer is just a minor inconvenience for any attacker. GPU accelerated cracking can smash through those with unnerving speed.

It’s also extremely doubtful that a password over 72 letters long is more secure than a 72 letter one. If that’s a random password, it’s already impossible to crack. That length is enough to accommodate even generously long pass-phrases, and most aggressively random passwords are 32-64 letters at most.

While opinions are fine, they don’t matter when you’re compromised, which is why I find these recommendations really concerning. Security is a huge responsibility when building a site that people will trust their passwords with. Don’t take short-cuts or be clever. Follow recommended best practices, and keep up to date with your techniques.

Today that means use Bcrypt and always encrypt your production data backups.

Collapse
 
devmazee2057282 profile image
dewbiez

Alright, thank you, means a lot.

Collapse
 
devmazee2057282 profile image
dewbiez

And why do you make it sound like it's so easy to break AES encryptions? Is it?

Collapse
 
tadman profile image
Scott Tadman

Since the application must keep the AES key around somewhere handy, in the event of a compromise it's going to get stolen as well and then your encryption is worthless as they have the key.

From there dealing with a single layer of HMAC is pretty trivial.

Collapse
 
devmazee2057282 profile image
dewbiez

But, I'm curious. What do you mean the HMAC seems really high risk?

Collapse
 
tadman profile image
Scott Tadman • Edited

HMAC is intended to be fast, which makes it ideal for crackers. For passwords you want something deliberately slow. Bcrypt is one such function, and it can be tuned to be even slower if you prefer.

For example, you can crunch through potentially a million passwords per second using a GPU-accelerated rig and software like HashCat if it's just HMAC-SHA3.

Bcrypt with default settings is around 13K per second on the same hardware. It's hundreds of times slower, plus you can increase the factor which can make it even slower still.

When protecting passwords you need to consider how long you need to keep them protected. Eventually every hashing method will be compromised, MD5 and SHA1 have been effectively beaten. By using a stronger Bcrypt setting you can make it harder to crack passwords on not just today's hardware, but hardware that exists ten years from now, protecting your application against future attacks.

Twenty-five years ago when using SHA-based password hashes it was inconceivable that a consumer-grade GPU could have several thousand threads, that would be more powerful than any supercomputer on the planet at the time. What hardware will exist twenty-five years from now? What if having a half-million threads is considered no big deal?

As much as twenty-five years seems like a long time, what if ten years from now your app gets hacked, and ten years after that the database starts floating around as part of a Torrent? Those passwords might still be in use, some people are really bad at changing them, which means you've got a responsibility to do your best to protect them.

There's a lot to understand here, but this post covers a lot of ground.

Thread Thread
 
devmazee2057282 profile image
dewbiez • Edited

Yeah, I used HashCat to attack a Bcrypt hash before. I could do roughly 10-11 thousand attempts per second.

You did take note I wasn't just HMACing and encrypting the password though, right? I don't want any confusion. I was using a password hashing function.

Thread Thread
 
tadman profile image
Scott Tadman

That's what makes Bcrypt so great. Smashing through a dictionary against a compromised database is painful, and you can make it even more painful by cranking up the difficulty factor. It's very resistant against brute force attacks.

HMAC is meant for other things, like signing, where you're not dealing with brute-force attacks, where instead performance, authentication and verification are what matters. It's not in any way intended for, nor suitable to use as a password hash.