Skip to content
This repository was archived by the owner on Apr 18, 2023. It is now read-only.

Jasypt usage guide & security principles explained

Miguel García García edited this page Feb 17, 2017 · 2 revisions

Introduction

Jasypt is a library which allows us to add basic encryption capabilities to our projects with the minimum effort.

Encrypting passwords

I'll explain briefly how the algorithm works as well as the principles it follows.

1. Encrypt using one-way techniques: digests

In almost every case, there's absolutely no reason for a password being decrypted. If you use password-based encryption (which is a two-way technique) and anyone gets to know your encryption password, all the passwords you've encrypted that way will be revealed. If you don't have such key to be able to decrypt, the risk simply dissapears (an attacker will then have to use different and less effective strategies, like brute force).

If a user loses his password, you can reset it to a new value and send him an email, but never remind it to them. You shouldn't even have a way to get your user's passwords, no matter what.

Several digesting algorithms can be applied, like MD5, or SHA family variants.

2. Match input and stored passwords by comparing digests, not unencrypted strings

When a user enters his password at login, the input will be digested in the same way we did when storing the password, and then compare both digests. Two equal inputs will have equal digests, but it doesn't work in the opposite direction.

3. Use a salt containing at least 8 random bytes and attach them, undigested, to the result

The salt is a sequence of bits added to the password before being digested. This makes digests to be different to what they would be if we encrypted the password alone, giving us protection against dictionary attacks.

Two different types of salt can be used: fixed or variable. In the case of using fixed salt, we would have to protect and store it, making it vulnerable to possible attacks. Variable salt is a better idea.

If we use a variable salt, its being random will force us to store it unencrypted along with the digest, so that we can recover it. This makes it trivial for attackers to know it, but our user's passwords would still remain decoupled from the rest, so that they would have to be attacked separately.

The minimum recommended size of salt is 8 bytes. If a mixed approach is used (a portion of the salt being fixed, and a portion being random), at least 8 of its bytes should be random.

4. Iterate the hash function at least 1000 times

The iteration count refers to the number of times that the hash function with which we are digesting is applied to its own results.

Salt and iteration count represented

Typical attacks

Performed on Description Defense
Brute force attacks Single user password The attacker tries to get the user's password by exhaustively generating all possible passwords, digesting them and testing if they match with the user's password digest By iterating the hash function i.e. 1000 times, the extra cost of creating the digest at sign up is not significant, but the accumulated cost for an attacker is huge
Dictionary attacks Single user password or database of user passwords as a whole The attacker tries to get the user's password by matching its digest against a set of most possible password digests, typically generated from a list of words in a dictionary By adding a random salt, the weakness of dictionary-based passwords many people use is reduced
Birthday attacks Databse of users passwords as a whole Having a large set of user password digests, the probability of generating a password which digest collides with at least one of the digests in the set is relatively high, and increases with the number of users By adding a random salt, its possiblities to succeed are minimum, since the attacker would have to attack each password separately, and not the set as a whole

Jasypt usage

Using Jasypt is very easy. We're going to see the code needed to encrypt and to check a password.

Encrypting a password

StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);

Checking a password

if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword)) {
  // correct!
} else {
  // bad login!

Sources

Official Jasypt documentation