When discussing secure storage of passwords, there are really two different sides to consider. First, during the registration process (or else during account provisioning, if that's how you're doing things), you have to obfuscate the password in some fashion before saving it to the data store. And secondly you have to be able to use those obfuscated passwords during authentication.
We're going to start with the authentication part first, since that's pretty easy to set up. We're going to assume the following:
Account
, with a corresponding AccountDao
interface and implementation to support CRUD operations.AccountServiceImpl
, that supports user
registrations. The registrations store the passwords as plaintext.applicationContext.xml
and applicationContext-security.xml
,
and you're using namespace configuration in applicationContext-security.xml
.Given the assumptions above, it isn't hard to modify the configuration to use hashed passwords during the login process. Let's see how.
Create an account or two in your database with SHA-1 hashed passwords. You can use the following website to compute SHA-1 hashes of plaintext passwords:
For example, the SHA-1 hash of flower
is 5a46b8253d07320a14cace9b4dcbf80f93dcef04
. When
entering your hash into the hash calculator at the link above, be sure not to enter a carriage return character, as
that's significant and will completely change the hash. Anyway, create the database records, using the SHA-1 hash as
the password.
We want to add something called a PasswordEncoder
to our Spring configuration. PasswordEncoder
is an interface defining a contract for computing hashes. There are different PasswordEncoder
implementations according to the hash function you want to apply. Two popular options, for example, are Md5PasswordEncoder
for MD5 hashes and ShaPasswordEncoder
for (you guessed it) SHA. We'll use SHA here but either choice is
legitimate. Don't use Md4PasswordEncoder
unless you are working with a legacy system, as it is known to
be weak.
The namespace configuration supports PasswordEncoder
s. Just add a single line to your authentication-provider
element like this:
<authentication-provider> <password-encoder hash="sha" /> <jdbc-user-service data-source-ref="dataSource" /> </authentication-provider>
Yep, that's it! This configuration sets SHA-1 as our hash algorithm.
Try logging in using the account you just created. Type in the plaintext password, not the hash. The login should work. If so, congratulations, your app authenticates against secure passwords! (You'll need to convert whatever other passwords you have into SHA-1 hashes.)
Now we're going to jump over to the other side, which is storing passwords securely during either the registration or account provisioning process. We'll assume a registration process but the technique is the same in either case.