[java] How can I hash a password in Java?

I need to hash passwords for storage in a database. How can I do this in Java?

I was hoping to take the plain text password, add a random salt, then store the salt and the hashed password in the database.

Then when a user wanted to log in, I could take their submitted password, add the random salt from their account information, hash it and see if it equates to the stored hash password with their account information.

This question is related to java passwords cryptographic-hash-function

The answer is


Among all the standard hash schemes, LDAP ssha is the most secure one to use,

http://www.openldap.org/faq/data/cache/347.html

I would just follow the algorithms specified there and use MessageDigest to do the hash.

You need to store the salt in your database as you suggested.


You could use Spring Security Crypto (has only 2 optional compile dependencies), which supports PBKDF2, BCrypt, SCrypt and Argon2 password encryption.

Argon2PasswordEncoder argon2PasswordEncoder = new Argon2PasswordEncoder();
String aCryptedPassword = argon2PasswordEncoder.encode("password");
boolean passwordIsValid = argon2PasswordEncoder.matches("password", aCryptedPassword);
SCryptPasswordEncoder sCryptPasswordEncoder = new SCryptPasswordEncoder();
String sCryptedPassword = sCryptPasswordEncoder.encode("password");
boolean passwordIsValid = sCryptPasswordEncoder.matches("password", sCryptedPassword);
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String bCryptedPassword = bCryptPasswordEncoder.encode("password");
boolean passwordIsValid = bCryptPasswordEncoder.matches("password", bCryptedPassword);
Pbkdf2PasswordEncoder pbkdf2PasswordEncoder = new Pbkdf2PasswordEncoder();
String pbkdf2CryptedPassword = pbkdf2PasswordEncoder.encode("password");
boolean passwordIsValid = pbkdf2PasswordEncoder.matches("password", pbkdf2CryptedPassword);

You can comput hashes using MessageDigest, but this is wrong in terms of security. Hashes are not to be used for storing passwords, as they are easily breakable.

You should use another algorithm like bcrypt, PBKDF2 and scrypt to store you passwords. See here.


In addition to bcrypt and PBKDF2 mentioned in other answers, I would recommend looking at scrypt

MD5 and SHA-1 are not recommended as they are relatively fast thus using "rent per hour" distributed computing (e.g. EC2) or a modern high end GPU one can "crack" passwords using brute force / dictionary attacks in relatively low costs and reasonable time.

If you must use them, then at least iterate the algorithm a predefined significant amount of times (1000+).


Here you have two links for MD5 hashing and other hash methods:

Javadoc API: https://docs.oracle.com/javase/1.5.0/docs/api/java/security/MessageDigest.html

Tutorial: http://www.twmacinta.com/myjava/fast_md5.php


i leaned that from a video on udemy and edited to be stronger random password

}

private String pass() {
        String passswet="1234567890zxcvbbnmasdfghjklop[iuytrtewq@#$%^&*" ;

        char icon1;
        char[] t=new char[20];

         int rand1=(int)(Math.random()*6)+38;//to make a random within the range of special characters

            icon1=passswet.charAt(rand1);//will produce char with a special character

        int i=0;
        while( i <11) {

             int rand=(int)(Math.random()*passswet.length());
             //notice (int) as the original value of Math>random() is double

             t[i] =passswet.charAt(rand);

             i++;
                t[10]=icon1;
//to replace the specified item with icon1
         }
        return new String(t);
}






}

BCrypt is a very good library, and there is a Java port of it.


As of 2020, the most reliable password hashing algorithm in use, most likely to optimise its strength given any hardware, is Argon2id or Argon2i but not its Spring implementation.

The PBKDF2 standard includes the the CPU-greedy/computationally-expensive feature of the block cipher BCRYPT algo, and add its stream cipher capability. PBKDF2 was overwhelmed by the memory exponentially-greedy SCRYPT then by the side-channel-attack-resistant Argon2

Argon2 provides the necessary calibration tool to find optimized strength parameters given a target hashing time and the hardware used.

  • Argon2i is specialized in memory greedy hashing
  • Argon2d is specialized in CPU greedy hashing
  • Argon2id use both methods.

Memory greedy hashing would help against GPU use for cracking.

Spring security/Bouncy Castle implementation is not optimized and relatively week given what attacker could use. cf: Spring doc Argon2 and Scrypt

The currently implementation uses Bouncy castle which does not exploit parallelism/optimizations that password crackers will, so there is an unnecessary asymmetry between attacker and defender.

The most credible implementation in use for java is mkammerer's one,

a wrapper jar/library of the official native implementation written in C.

It is well written and simple to use.

The embedded version provides native builds for Linux, windows and OSX.

As an example, it is used by jpmorganchase in its tessera security project used to secure Quorum, its Ethereum cryptocurency implementation.

Here is an example:

    final char[] password = "a4e9y2tr0ngAnd7on6P১M°RD".toCharArray();
    byte[] salt = new byte[128];
    new SecureRandom().nextBytes(salt);
    final Argon2Advanced argon2 = Argon2Factory.createAdvanced(Argon2Factory.Argon2Types.ARGON2id);
    byte[] hash = argon2.rawHash(10, 1048576, 4, password, salt);

(see tessera)

Declare the lib in your POM:

<dependency>
    <groupId>de.mkammerer</groupId>
    <artifactId>argon2-jvm</artifactId>
    <version>2.7</version>
</dependency>

or with gradle:

compile 'de.mkammerer:argon2-jvm:2.7'

Calibration may be performed using de.mkammerer.argon2.Argon2Helper#findIterations

SCRYPT and Pbkdf2 algorithm might also be calibrated by writing some simple benchmark, but current minimal safe iterations values, will require higher hashing times.


While the NIST recommendation PBKDF2 has already been mentioned, I'd like to point out that there was a public password hashing competition that ran from 2013 to 2015. In the end, Argon2 was chosen as the recommended password hashing function.

There is a fairly well adopted Java binding for the original (native C) library that you can use.

In the average use-case, I don't think it does matter from a security perspective if you choose PBKDF2 over Argon2 or vice-versa. If you have strong security requirements, I recommend considering Argon2 in your evaluation.

For further information on the security of password hashing functions see security.se.


You can use the Shiro library's (formerly JSecurity) implementation of what is described by OWASP.

It also looks like the JASYPT library has a similar utility.


Fully agree with Erickson that PBKDF2 is the answer.

If you don't have that option, or only need to use a hash, Apache Commons DigestUtils is much easier than getting JCE code right: https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html

If you use a hash, go with sha256 or sha512. This page has good recommendations on password handling and hashing (note it doesn't recommend hashing for password handling): http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html