Passwords have been used throughout history to verify someone's identity by checking if they possess the knowledge required (i.e., a password) to access something.
In Ancient Rome, a new watchword was assigned every day and engraved into a tablet. Roman soldiers had to retrieve the tablets every evening at sunset and share them with their unit so that they would know the watchword for the following day. These watchwords were required for soldiers to identify themselves as Roman soldiers so they could enter certain areas.
Since then, we've been using watchwords, now known as passwords, to verify someone's identity.
But does possessing knowledge of something actually confirm one's identity? In this article, you'll learn what username and password authentication is, some of the challenges that come with it, and one simple solution to address most of these challenges.
What is Username and Password Authentication
Authentication is the process of verifying who a user claims to be.
There are three factors of authentication:
- What you know — Something you know, such as a password, PIN, personal information like mother's maiden name, etc.
- What you have — A physical item you have, such as a cell phone or a card.
- What you are — Biometric data, such as fingerprint, retina scan, etc.
Password authentication falls into the "what you know" category and is the most common form of authentication.
Every time you've signed up for a website, you've likely been asked to create a username and password. Because this is such a common process now, it's become almost second-nature for some users to set up their accounts without much thought about the credentials they choose. And unfortunately, there's a lot at stake if a user chooses weak credentials.
How to Implement Password Authentication
Let's take a look at what goes on behind the scenes during the authentication process.
Registering with username and password
When a user first signs up for your website, they're asked to choose a username and password to identify themselves.
In an ideal world, the user would always pick a strong and unique password so that it's harder for an attacker to guess. Unfortunately, we don't live in an ideal world. For this reason, it's up to you as the developer to enforce this.
Enforcing password rules
When it comes to password safety, the longer and more complex the password is, the better.
It's a good practice to enforce certain minimum requirements when asking users to create a new password. Of course, you have to find a balance between these requirements and user experience. If you make the sign-up process too tedious, you could be driving users away.
To enforce password strength, you should define a set of rules that a password must satisfy and then enforce these with form validation.
Example password strength rules:
- Minimum of 8 characters
- At least one uppercase letter
- At least one number
- At least one special character
Storing the user's credentials
Once the user chooses their username and password and clicks submit, then the real fun begins: storing the user's credentials.
First, you have to check that the user doesn't already exist in the database. Once that's clear, you should again check that their password matches your minimum requirements, but this time you'll be confirming server side.
Once you decide that the credentials should be stored, it's time to save them to your database. However, there's one more step that must occur before you can do this: password hashing.
Hashing — Password hashing involves using a one-way cryptographic function that takes an input of any size and outputs a different string of a fixed size.
Before you store any passwords in your database, you should always hash them. The hashed password will be unrecognizable from the plaintext password, and it will be impossible to regenerate the plaintext password based on the hashed one. If someone gains access to your database, you don't want them to be able to swipe your entire users table and immediately have access to all user login credentials. That's why it's absolutely essential to hash your passwords.
ℹ️ Make sure you use a secure and vetted hashing algorithm when implementing password hashing.
Most programming languages will have either built-in functionality for password hashing or an external library you can use. bcrypt is one popular library that can help you hash passwords. Whatever you do, make sure you don't try to roll out your own hashing algorithm.
✏️ To learn more about bcrypt, check out this excellent article: Hashing in Action — Understanding bcrypt.
Handling returning users
After your users' register, they're hopefully going to want to come back, and when they do, you need to verify that they are who they say they are.
Once they submit their credentials through the login form, you'll search your database for the username they're signing in with. If you get a match, then you check the hashed password that they typed in with the hashed password stored in your database.
Now that your users are able to sign up and log back in, you still have one more case to handle. What do you do if a user forgets their credentials? In this case, let's assume that the username that you required users to sign in with was an email address. You'll need to generate a password reset link, email that to the user, and allow them to set a new password.
Because you have the user's hashed password stored in the database, and you used a one-way hashing function, there's no way to let the user know what their old password was. Therefore, they'll have to reset their password.
Implementing with Auth0
Implementing all of this takes a lot of work. With Auth0, you can add username and password authentication to your application in just minutes.
🔥 You can sign up for a free Auth0 account now to get started immediately.
Once you have an account, head over to the Auth0 Quickstarts page for an easy-to-follow guide on implementing authentication using the language or framework of your choice.
In the next section, you'll see some of the challenges of password authentication. Keep in mind, Auth0 has built-in solutions for all of these challenges as well.
Challenges of Password Authentication
Username and password authentication is a great starting point, but it's just not enough. Let's look at some of the challenges that come with password authentication.
The implementation, intuitively, seems pretty bulletproof. You required your users to choose passwords with a certain complexity, and you hashed the passwords before storing them so that in the event your database is breached, the attackers won't have a goldmine of user login credentials. Great, right?
Well, not so fast.
Password attack methods
Even with these safeguards in place, password authentication is still vulnerable to a multitude of attacks. Let's take a look at some of these.
Credential stuffing attacks — An automated attack where the attacker repeatedly tries to sign in to an application using a list of compromised credentials, usually taken from a breach on a different application.
The credential lists used in credential stuffing attacks come from previously breached data across the web that a bad actor got their hands on. These attacks are extremely prevalent and have become one of the most widely used password attack methods. Even at Auth0, almost half of the login requests we receive daily are attempts at credential stuffing.
This begs the question, why would any of these credentials even work if they were stolen from a different application? The short answer is, users reuse their passwords!
Most people have hundreds of online accounts, so it would be virtually impossible to memorize every single login combination without a password manager. According to some research, less than 25% of people use password managers. For those that don't, there's a pretty good chance they're reusing the same password across multiple accounts, or even worse, all accounts.
Rainbow table attacks — An attack that attempts to crack a hashed password by comparing it to a database of pre-determined password hashes, known as a rainbow table.
Earlier, you learned about why it's important to always hash passwords before storing them. If an attacker gains access to your database, you don't want them to have immediate access to plaintext passwords, so you hash them. While this does make it more difficult for a bad actor to exploit, it's still not impossible.
A rainbow table will take frequently used passwords, hash them using a common hashing algorithm, and store the hashed password in a table next to the plaintext password. Then, if an attacker gains access to a database that contains hashed passwords, they can compare the stolen hashes to those that are pre-computed in the rainbow table. If any of the hashes match, then they will know the original plaintext password.
Brute force attacks — An attack that uses trial and error to try out every combination of possible passwords until the correct one is found.
This isn't the most efficient way to crack a password, but it can produce results nonetheless. You may be surprised at how fast a computer can brute force a seemingly complicated password. If you're curious, How Secure is My Password is an awesome tool that you can play around with to see how fast any password can be cracked.
As you can see, username and password authentication still has some pitfalls, especially if done incorrectly. Luckily, there's a simple way to combat all of these challenges: multi-factor authentication.
Multi-factor authentication involves bringing in an additional factor (what you know, what you have, what you are) on top of the username and password combination to identify a user. In this case, you already have "what you know" covered with the username and password, so the additional factor would have to come from one of the other two categories. This can be something as simple as a text message to the user's phone to verify that they are who they say they are after they sign in with their credentials.
One analysis by Microsoft has suggested that multi-factor authentication could have stopped up to 99.9% of credential stuffing attacks!
To learn more about multi-factor authentication and how you can enable it on your own application, check out the Multi-factor Authentication Guide.
Auth0 provides a platform to authenticate, authorize, and secure access for applications, devices, and users. Security and application teams rely on Auth0's simplicity, extensibility, and expertise to make identity work for everyone. Safeguarding billions of login transactions each month, Auth0 secures identities so innovators can innovate, and empowers global enterprises to deliver trusted, superior digital experiences to their customers around the world.