(For more resources related to this topic, see here.)
We have now successfully learned how to secure our users' passwords using hashes; however, we should take a look at the big picture, just in case.
The following figure shows what a very basic web application looks like:
Note the https transmission tag: HTTPS is a secure transfer protocol, which allows us to transport information in a secure way. When we transport sensitive data such as passwords in a Web Application, anyone who intercepts the connection can easily get the password in plain text, and our users' data would be compromised.
In order to avoid this, we should always use HTTPS when there's sensitive data involved. HTTPS is fairly easy to setup, you just need to buy an SSL certificate and configure it with your hosting provider. Configuration varies depending on the provider, but usually they provide an easy way to do it.
It is strongly suggested to use HTTPS for authentication, sign up, sign in, and other sensitive data processes. As a general rule, most (if not all) of the data exchange that requires the user to be logged in should be protected. Keep in mind that HTTPS comes at a cost, so try to avoid using HTTPS on static pages that have public information.
Always keep in mind that to protect the password, we need ensure secure transport (with HTTPS) and secure storage (with strong hashes) as well. Both are critical phases and we need to be very careful with them.
Now that our passwords and other sensitive data are being transferred in a secure way, we can get into the application workflow. Consider the following steps for an authentication process:
- The application receives an Authentication Request.
- The Web Layer takes care of it as it gets the parameters (username and password), and passes them to the Authentication Service.
- The Authentication Service calls the Database Access Layer to retrieve the user from the database.
- The Database Access Layer queries the database, gets the user, and returns it to the Authentication Service.
- The Authentication Service gets the stored hash from the users' data retrieved from the database, extracts the salt and the amount of iterations, and calls the Hashing Utility passing the password from the authentication request, the salt, and the iterations.
- The Hashing Utility generates the hash and returns it to the Authentication Service.
- The Authentication Service performs a constant-time comparison between the stored hash and the generated hash, and we inform the Web Layer if the user is authenticated or not.
- The Web Layer returns the corresponding view to the user depending on whether they are authenticated or not.
The following figure can help us understand how this works, please consider that flows 1, 2, 3, and 4 are bidirectional:
The Authentication Service and the Hashing Utility components are the ones we have been working with so far. We already know how to create hashes, this workflow is an example to understand when we should it.
In this article we learned how to create hashes and have now successfully learned how to secure our users' passwords using hashes. We have also learned that we need to ensure secure transport (with HTTPS) and secure storage (with strong hashes) as well.
Resources for Article:
- FreeRADIUS Authentication: Storing Passwords [Article]
- EJB 3.1: Controlling Security Programmatically Using JAAS [Article]
- So, what is Spring for Android? [Article]