Encrypting passwords

If you want to read about how passwords should be encrypted, how you would defend from attacks on your user password database, and why you should use jasypt for encrypting your passwords, have a look at this article: How to Encrypt User Passwords.

Digest creation process with jasypt's Standard[Byte|String]Digester

[The techniques seen here also apply to the provided implementations of org.jasypt.util.password.PasswordEncryptor]

The steps taken in jasypt's standard digesters for creating digests are:

  1. A salt of the specified size is generated (see org.jasypt.salt.SaltGenerator). If salt size is zero, no salt will be used. It is advisable that you use a random salt generator like org.jasypt.salt.RandomSaltGenerator (which is the default) for higher security.
  2. The salt bytes are appended at the beginning of the message.
  3. The hash function is applied to the salt and message altogether, and then to the results of the function itself, as many times as specified (iterations).
  4. If using a random salt generator, the undigested salt is appended at the beginning of the hash result.

Put schematically in bytes:

  • DIGEST = |S|..(ssb)..|S|X|X|X|...|X|
    • S: salt bytes (plain, not digested). (Only if using a random salt generator).
    • ssb: salt size in bytes.
    • X: bytes resulting from hashing (see below).
  • |X|X|X|...|X| = H(H(H(..(it)..H(Z|Z|Z|...|Z|))))
    • H: Hash function (algorithm).
    • it: Number of iterations.
    • Z: Input for hashing (see below).
  • |Z|Z|Z|...|Z| = |S|..(ssb)..|S|M|M|M...|M|
    • S: salt bytes (plain, not digested).
    • ssb: salt size in bytes.
    • M: message bytes.

When using a random salt generator, two digests created for the same message will always be different (except in the case of random salt coincidence or no usage of salt). Because of this, in this case the result of the digest method will contains both the undigested salt and the digest of salt+message, so that another digest operation can be performed with the same salt on a different message to check if both messages match (all of which will be managed automatically by the matches method).

Also, when using StandardStringDigester, the resulting digest Strings are BASE64 encoded (or hexadecimal, if you prefer) to avoid charset issues. This output encoding can be chosen with the setStringOutputType method.