I know you gotta store the passwords hashed but doesn’t that just move the goalposts? How come someone can’t use the hashed end result to get into the service it was used for?
I know you gotta store the passwords hashed but doesn’t that just move the goalposts? How come someone can’t use the hashed end result to get into the service it was used for?
Yes, kinda. Security isn’t about making things 100% secure, that’s not really an achievable goal. It’s about making it so hard to break the security that it’s either not possible with current technology, or at least hard enough that it’s not financially feasible. Password hashing is a great example for this, which gets to your second question:
They can, though there are technical methods for preventing this. But, there is a whole class of attacks called Pass the Hash which do basically this. This is also part of the reason that many organizations are moving away from passwords alone (or at all) and more towards things like Pass Keys (which work in an entirely different way) or Two factor authentication, which pair a password with something else (biometrics, One Time Passwords, etc.).
To dig into the details of why passwords are hashed (and salted), it’s important to consider why that is recommended. This is really about slowing down an attacker’s ability to get your password back from the hash. Consider for a moment that I go and compromise a website’s server (say, lemmy.world). One of the pieces of information I am going to try and get away with (exfiltrate) is the database of usernames and passwords. Even better if that data is tied to email addresses. Now, if all of the passwords are stored in plain text, I can immediately start using those usernames and passwords both on the compromised site, but also on other sites across the internet. Many people still reuse passwords (or similar enough passwords that I can guess them) across different sites. Maybe only 0.1% of users will have the same email address and password used on their bank account as they do on the compromised website. For 10,000 users, that means I get to drain the bank accounts of 10 of them. If I average $1000 from each, that’s an easy $10,000 I walk away with, with almost zero effort.
Hashing makes this harder and take longer. First off, there is no mathematical way for me to go from a hash back to a password, it’s literally impossible. What I have to do is guess a password, run it though the hashing algorithm and see if that guess is a match. So, I guess “Password1” and that hashes to something, if it’s not a match, I try “Password2” and check if it is a match, and so on. Unlike the movies, I cannot discover the password one character at a time, either I get it perfectly right or I don’t, there is no information in between. If your password is “Password3”, I will get no information by guessing “Password2”. I’ll just know that “Password2” wasn’t your password. And while calculating a single hash value is reasonably quick, when the number of possible passwords I need to guess is mind-mindbogglingly big, the small increments of time add up really fast.
For example, my Lemmy password is exactly 16 characters. It contains the usual combination of upper and lower case letters, numbers and special characters. Let’s call this 70 possible characters in each position. So, there are 70^16 possible passwords, that is 332,329,305,696,000,000,000,000,000,000 possible passwords (assuming my calculator isn’t truncating digits, but close enough). If we assume Lemmy is using bcrypt (I haven’t checked) and the attacker has several modern GPUs to throw at the problem, they might be guessing 1,000,000 or so passwords per second (maybe a bit more or less, but what’s a few zeros between fiends). That translates to 3.32329305696 * 10^23 seconds of guessing, or about 10,000,000,000,000,000 years (rounding a bit). That’s likely a few years longer than I will have a Lemmy account. Even if they are guessing a thousand times faster than I used in my example, it’s still a really, really long time.
And so this is why hashing is exactly about “mov[ing] the goalposts”. All we’ve done is make it take a bit longer to get my password from the hash. But that “a bit” gives the defenders time to discover the breach and get users to update their passwords. If someone gets my password hash today and starts guessing, as long as Lemmy lets me know about it and I update my password before the heat death of the Universe, it’s probably fine.
There are some caveats to this. People are actually pretty bad at choosing passwords (me included). And we tend to pick predictable things and use common words or numbers (like birthdays). So, instead of guessing every possible combination, attackers can use wordlists with common changes to those words (numbers at the start or end, symbols at the start or end, replacing letters with numbers such as 1337 sp3@k, etc.) to crack some passwords faster. Which is one reason network defenders are pretty quick to pull the “please change your password” lever. They have no way of knowing if your password is “I Love Puppies 99!” or “r39%^0m’AferF@&B”. The former would fall out of a wordlist attack pretty fast, the latter is in the “heat death of the Universe” territory. You can also go in for Diceware passwords. Using 4-5 truly random words can also push that password cracking time close enough to “never”.
So, “doesn’t that just move the goalposts?”
Yup, it is. But when the goal posts are moved to “this will now take more time than might ever actually exist”, that’s plenty far enough.
Not included in this answer and I’m not fully qualified to talk about: salting.
If you knew the hashing algorithm, you could precompute hashes of all the common passwords. Then when you get steal the hashed password data, it’s a lot faster to check if any of them are in your list. You can likely find that kind of list online to download.
One defense against this is “salting”. The site adds some text to your password before hashing it. So if your password is extremely common, like “password1!”, with the added salt the hash on this site will be different. Like maybe it adds the user’s uuid, so what gets hashed is “password1!-abcd-123-pretend-this-is-a-uuid”. The user doesn’t need to know.
Another benefit is that now two passwords that both are “password1!” have different hashes.
I’m not an expert by any means so please someone correct me if anything was wrong there.
Thanks for adding that. I mentioned salting in a parenthetical and then completely ignored it. This is a good addendum.
That’s a really good explanation.
Might steal this.
You made this, this is yours now.
I count 16 characters. Must be your password
Give it a try, it might be. I actually have no clue what my Lemmy password is. I just semi-randomly smooshed out 16 characters. I use KeePassXC as a password vault and I let it generate, store and usually type my passwords for me. I haven’t the slightest clue what most of them are and can’t be arsed to care. I did check the length of my password while typing up my comment, but other than mentally processing the number of characters, I wasn’t paying attention to it.
Thanks! This is the kind of response I needed