Remember that last video I made? The one where I told you how great hashing is?
As usual, it's a little more complicated than that.
Look, people are bad at making passwords. And the more you click on that "forgot my password"
button, the more you realize that you would rather have your password be short, simple,
and easy to remember. If we lived in a world where everyone's password was 50 random characters long,
then maybe I wouldn't need to make this video. Hashing would probably be enough.
But humans are creatures of habit, with brains that usually cannot remember a
single string of 50 random characters, much less a different 50 random character string
for each of the hundreds of websites they use, at least without a decent password manager.
So here we are, stuck in the real world, with real world people with real bad passwords.
But fortunately, we have technology! Computers! Programs! Isn't that great!
I say that with the slightest hint of irony because in security, we have a never-ending
war between attackers and defenders, each side leveraging their own computers and programs.
I guess people back in the day didn't have to worry about hashes.
[Sigh]
So there are a lot of issues.
Suppose you have a hacker. They haven't stolen anything yet, haven't broken into any websites
or databases, but you know, in the future, they might want to. The only thing they know
about a particular website, let's say Big Bank Incorporated, is that they use a very
common hashing algorithm to store the hashes of their user's passwords instead of the original
password. Great! The hacker decides, because they're bored one day, to start hashing the
top 200 most common passwords, creating a file of many password and hash combinations.
Remember, the hash function is consistent, regardless of whether the hacker uses it or
the bank uses. It will always produce the same result, otherwise we would never be able to
use it to verify the password a user gives you is the same one they used to register.
But why stop at the top 200 passwords? Modern day computers can calculate hundreds of millions
of hashes per second. Sure, there are a lot of passwords to hash, but hacker is in no rush,
and knows that users tend to have shorter and predictable passwords. So although they might
never be able to try every combination of 15 character long passwords, they can start with
5 character long passwords, move on to 6 long 7, and so on until eventually they get bored.
If you take these 95 characters as the set of characters you can use in your password, going
at 600 million hashes per second, you can crack every single password of length 5 in 13 seconds,
all characters of length 6 in 20 minutes, all passwords of length 7 in a day and a half,
and all passwords of length 8 in about 4 months.
Remember, they're not doing anything with these passwords and hashes, they're just holding on to
them for a rainy day. In theory, they don't have to just brute force it either, there are plenty of
clever ways to exploit the patterns that humans like to make their passwords. How many of you
put a 1 at the end of your password? Or replace s's with dollar signs or I's with exclamation
points? Or end your password in the year you created the account or someone's birthday.
These kinds of patterns are all things that allows hackers to speed up the process, skipping shorter
passwords that seem rare and unlikely and focusing on those that yield more promising results.
Skip three years down the line,
there's a data breach. Big Bank Incorporated has had million's of user's data stolen!
Fortunately for them, they had the decency to store hashes of their passwords instead
of the actual password. Good! But turns out, for a lot of those users, this won't even help them.
Suppose Steve has a really common password,
something that appears in the top 200 passwords list.
Let's say, it's "pokemon". Really? Your password is "pokemon"? Great. Great password, love it.
So this hacker, doesn't know that Steve's password is "pokemon", because the database he
stole doesn't have the original passwords, it only has the hashes. But the hacker knows that Big Bank
hashed it with the same hashing function as the hacker used to create their database of the top
200 passwords and their hashes. On that list, is the password "pokemon", and hacker notices
that the hash of the password "pokemon" matches the hash next to Steve's name exactly. Hacker
now knows that Steve's password is "pokemon". In fact, now they know every single user who uses the
password "pokemon", or anything else on that top 200 list. That's of course only if Hacker stopped
hashing after the top 200 passwords. If they kept going on for a minute, or a day, or a year, they
could be able to figure out everyone's password if that password was 8 characters long or less.
This process took a bit of planning, about 4 months, but the day that Big Bank had their
passwords stolen, hacker was able to immediately determine the passwords of a huge chunk of the
users, almost as if Big Bank didn't hash those passwords in the first place. The problem? The
hash of "pokemon" will always be the same. It will be the same when Hacker does it and when
Big Bank does it. Of course this is the whole point of the hash function in the first place,
like any function with the same input, it will always yield the same
output. A random looking result for sure, but a consistent result nonetheless.
Hacker has precomputed all these hashes by brute force, and now will be able to get into your bank
account if your password matches any on their list the day that they get their hands on these files.
In comes the technology: Introducing, SALTS!
Well, okay, hang on, Salts don't actually fully solve this problem,
BUT LET ME TALK ABOUT THEM FIRST, and then we can discuss.
Salts are basically a random string that you generate and can attach to the end of the
password that a user gives you before passing it into the hash function. It's randomly generated
when they first sign up for your website, and is unique to that specific user. So like before,
someone gives us the password, password1, we put it through the hash function, it gives us
a bunch of nonsense, right? So now, instead of doing that, we append this little bit of fluff,
the salt, at the end, and hash this new "password + salt" instead, and it gives us a different,
totally different hash! Great, why is this a good idea? Because now, even if I precompute the hash
of "password1", which would probably appear in the top 200 most common passwords, it's not
particularly helpful. The hash stored by Big Bank in this database is not the hash of "password1",
it's the hash of "password1jv6}"… so on. So the hash of "password1" that appears in hacker's files
doesn't look anything like the hash that appears in Big Bank's database.
So that means we can't just look at the top 200 most common passwords and stuff. Because
"password1" might be a very common password, but "password1jv6}" so on, obviously is not as common.
Who cares if you've pre-computed the hash of "password1"? From the databases' point of view,
no one has that password anymore! This also has the added bonus of making users
who have the same password as other users have completely different hashes from each other,
because their salts are different. The hash of this is completely different from the hash
of that, so they can't even do any of the clever analysis to try and figure out which people have
the same passwords. Before, when we weren't using salts, we could go through Big Bank's database,
and if a hash appears a bunch of times, we know that all those users share the same password,
which could be useful information for the hackers. Now with salts, each of those
users will have a different salt, therefore a different hash, and hackers can't even do that.
Well this is nice. Hey! You can also sorta think of this like artificially increasing
the length of your password! Right? Like if we have a password "apple", 5 characters long,
and then we add thirty characters of random nonsense at the end as a salt then it's kinda
like we have a password of 35 random characters, not just 5. Which is really nice, because then
that table that those hackers created over four months? Well those only accounted for passwords
of length 8 or less. Certainly it doesn't contain hashes for really long passwords!
So great, here's how the flow works. When a user creates an account, they give you a password.
You generate a salt, random characters, fairly long, you push these two things together,
and pass it through the hash function! Then, you store three things! The username, the salt,
and this new hash! Remember, we don't want to store their original password,
because if it is stored, it can be stolen! Anything here, we can let them steal,
and it'll be useless information for the techniques we just described!
So when a user tries to log in again, they give us a password, we take their salt, put it at
the end of their password, pass it through the hash function, and if the hashes match,
then we know that this password is the same they've given us back when they registered!
This actually helps quite a bit. This means that these tables of passwords and their hashes that
you can compute and share with all your hacker friends aren't as useful. There are techniques
that they may use to efficiently store many many different password/hash combinations,
but at a certain point, these tables don't really matter. If you have random and long passwords,
then at a certain point, there just isn't a good way to compute every single one of them,
much less store it. And like I said before, you can't just guess random common passwords anymore.
So what's the issue here? Remember, everything that is stored, can be stolen.
So if the hooded hackers gets their hands on all your data, then they also have your salts,
don't they? Remember, you left them right next to those usernames.
So it seems like we're back to square one. Sure, you can't use precomputed hash tables anymore,
but if you know that they're using a hashing and salt algorithm, and you have their salt,
why not just try the top 200 passwords, with this salt attached to it? And then, why stop there?
Do all the passwords that are 6, 7, 8 characters long. Guess what, bad password + the same random
string every single time is just as broken as a normal bad password, if you know what the random
string is. Sure, the salt is unique to each user, they probably won't break everyone's bad
passwords, but they could certainly target some CEO or something, and you certainly don't want
anyone's password to be broken, even if you're not cracking a billion passwords at once.
So again, in less than a milisecond, if your password is very common or "guessable",
then if I have access to the salt, then your password just isn't secure.
If it's 8 characters long, sure, it's a pain, I basically have to compute everything from scratch
with this new salt, but again, in 4 months, you'll know exactly what that password is.
You can't do it all at once like you used to, but for any given user,
their password is only 4 months away from being broken after this database is stolen.
The advantage of this approach is that they can't pre-compute the hashes. They need to steal the
hashes and salts, and then start cracking, they can't generate a table back in 2015 and then steal
something in 2019 and hope to use that table they created. They have to have everything, crack one
password at a time, and then once they do it, they can't share that knowledge with others.
Sure, a much needed improvement over just hashing, but does not ultimately solve the issue here.
The solution? Slow the hackers down. See, some hashing algorithms can hash hundreds of
millions of passwords per second. But these aren't the best ones for password storing.
Sure, they have many other great uses, which we will get into,
but in this case, we need a hashing algorithm that takes a much longer time to compute hashes.
And one, that hopefully, is adjustable so that even as computers get faster and faster,
then the hashing algorithm can also be modified to be slower and slower.
Thus enters the technology: bcrypt. A combination of Hashing + Salting + an adjustable parameter for
the iteration count, which allows us to control how long the hashing algorithm takes. Computers
getting twice as fast over time? That's fine, just increase the parameters to make sure that
the hashing algorithm is slower. Brute forcing a password by trying every single combination
of characters then becomes incredibly slow, and because of the salt, precomputing hashes isn't
going to be particularly helpful anymore. At that point, the hackers will have to steal the database
of hashes, and calculate each password, one by one, a thousand, million, billion times slower.
But we can get into that later. If you're interested in seeing more,
like the video! Subscribe if you haven't already, show your support in the comments. Thanks for all
the support so far. And uh, yeah if I said your password somewhere in this video… Go change it :)