How can I hash a password in Java?
Asked Answered
K

14

204

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.

Korte answered 18/5, 2010 at 20:35 Comment(6)
Better to use the SHA family of hash functions. en.wikipedia.org/wiki/MD5 (although nothing is perfect)Thoracoplasty
@Thoracoplasty this is actually not a recombination nowadays with GPU attacks being so cheap, SHA family is actually a very bad choice for password hashing (too fast) even with salt. Use bcrypt, scrypt or PBKDF2Oxymoron
Why was this question closed? This is a question for a real engineering problem, and the answers are invaluable. The OP is not asking for a library, he is asking how to solve the engineering problem.Pupiparous
Just amazing. This question has 52 upvotes, and someone decides to close it as "off-topic".Pupiparous
Yeah, I've posted on Meta about this issue of closings before, got beaten up pretty badly though.Korte
This question should be re-opened. It's a question about how to write a program to solve the problem described (password authentication), with a short code solution. Seeing the trigger word "library" doesn't justify reflexively closing a question; he's not asking for a library recommendation, he's asking how to hash passwords. Edit: There, fixed it.Faa
F
169

You can actually use a facility built in to the Java runtime to do this. The SunJCE in Java 6 supports PBKDF2, which is a good algorithm to use for password hashing.

SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 128);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
System.out.printf("salt: %s%n", enc.encodeToString(salt));
System.out.printf("hash: %s%n", enc.encodeToString(hash));

Here's a utility class that you can use for PBKDF2 password authentication:

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
 * Hash passwords for storage, and test passwords against password tokens.
 * 
 * Instances of this class can be used concurrently by multiple threads.
 *  
 * @author erickson
 * @see <a href="https://mcmap.net/q/36249/-how-can-i-hash-a-password-in-java">StackOverflow</a>
 */
public final class PasswordAuthentication
{

  /**
   * Each token produced by this class uses this identifier as a prefix.
   */
  public static final String ID = "$31$";

  /**
   * The minimum recommended cost, used by default
   */
  public static final int DEFAULT_COST = 16;

  private static final String ALGORITHM = "PBKDF2WithHmacSHA1";

  private static final int SIZE = 128;

  private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})");

  private final SecureRandom random;

  private final int cost;

  public PasswordAuthentication()
  {
    this(DEFAULT_COST);
  }

  /**
   * Create a password manager with a specified cost
   * 
   * @param cost the exponential computational cost of hashing a password, 0 to 30
   */
  public PasswordAuthentication(int cost)
  {
    iterations(cost); /* Validate cost */
    this.cost = cost;
    this.random = new SecureRandom();
  }

  private static int iterations(int cost)
  {
    if ((cost < 0) || (cost > 30))
      throw new IllegalArgumentException("cost: " + cost);
    return 1 << cost;
  }

  /**
   * Hash a password for storage.
   * 
   * @return a secure authentication token to be stored for later authentication 
   */
  public String hash(char[] password)
  {
    byte[] salt = new byte[SIZE / 8];
    random.nextBytes(salt);
    byte[] dk = pbkdf2(password, salt, 1 << cost);
    byte[] hash = new byte[salt.length + dk.length];
    System.arraycopy(salt, 0, hash, 0, salt.length);
    System.arraycopy(dk, 0, hash, salt.length, dk.length);
    Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding();
    return ID + cost + '$' + enc.encodeToString(hash);
  }

  /**
   * Authenticate with a password and a stored password token.
   * 
   * @return true if the password and token match
   */
  public boolean authenticate(char[] password, String token)
  {
    Matcher m = layout.matcher(token);
    if (!m.matches())
      throw new IllegalArgumentException("Invalid token format");
    int iterations = iterations(Integer.parseInt(m.group(1)));
    byte[] hash = Base64.getUrlDecoder().decode(m.group(2));
    byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8);
    byte[] check = pbkdf2(password, salt, iterations);
    int zero = 0;
    for (int idx = 0; idx < check.length; ++idx)
      zero |= hash[salt.length + idx] ^ check[idx];
    return zero == 0;
  }

  private static byte[] pbkdf2(char[] password, byte[] salt, int iterations)
  {
    KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE);
    try {
      SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM);
      return f.generateSecret(spec).getEncoded();
    }
    catch (NoSuchAlgorithmException ex) {
      throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex);
    }
    catch (InvalidKeySpecException ex) {
      throw new IllegalStateException("Invalid SecretKeyFactory", ex);
    }
  }

  /**
   * Hash a password in an immutable {@code String}. 
   * 
   * <p>Passwords should be stored in a {@code char[]} so that it can be filled 
   * with zeros after use instead of lingering on the heap and elsewhere.
   * 
   * @deprecated Use {@link #hash(char[])} instead
   */
  @Deprecated
  public String hash(String password)
  {
    return hash(password.toCharArray());
  }

  /**
   * Authenticate with a password in an immutable {@code String} and a stored 
   * password token. 
   * 
   * @deprecated Use {@link #authenticate(char[],String)} instead.
   * @see #hash(String)
   */
  @Deprecated
  public boolean authenticate(String password, String token)
  {
    return authenticate(password.toCharArray(), token);
  }

}
Faa answered 18/5, 2010 at 20:58 Comment(26)
You may want to be a bit wary of byte to hex conversions with BigInteger: leading zeros are removed. That's ok for quick debug, but I have seen bugs in production code due to that effect.Landre
Thanks for this (+1). I'm constrained to Java 5. Is PBEWithHmacSHA1AndDESede a sufficiently strong algo?Biaxial
Yes, it's true that these salt and hash values should be treated as numbers, not strings, for repeatable results.Faa
@thomas-pornin's highlights why we need a library, not a code block that's almost there. Scary that the accepted answer does not answer the question on such an important topic.Rhianna
Use the algorithm PBKDF2WithHmacSHA512 starting with Java 8. It is a bit stronger.Kee
@Faa I am nor very much into what the best algorithm is. But I checked what algorithms are available in which Java versions. Hope that helps:Kee
Note, existing algs are not deleted in later versions: java_4:PBEWithMD5AndDES,DESede,DES java_5/6/7:PBKDF2WithHmacSHA1,PBE (only in Java 5),PBEWithSHA1AndRC2_40,PBEWithSHA1And,PBEWithMD5AndTriple java_8:PBEWithHmacSHA224AndAES_128, PBEWithHmacSHA384AndAES_128, PBEWithHmacSHA512AndAES_128, RC4_40, PBKDF2WithHmacSHA256, PBEWithHmacSHA1AndAES_128, RC4_128, PBKDF2WithHmacSHA224, PBEWithHmacSHA256AndAES_256, RC2_128, PBEWithHmacSHA224AndAES_256, PBEWithHmacSHA384AndAES_256,PBEWithHmacSHA512AndAES_256,PBKDF2WithHmacSHA512,PBEWithHmacSHA256AndAES_128, PBKDF2WithHmacSHA384,PBEWithHmacSHA1AndAES_256Kee
@ThomasPornin Replaced hex by BigInteger with padded base-64.Faa
@Kee In an HMAC, NIST suggests that SHA-1 will provide 128 bits of security, while SHA-224 or SHA-256 provide at least 192 and 256 bits, respectively. Match those algorithms with the AES key length you want to generate. Of course key derivation doesn't create entropy. It would be hard for a person to pick and remember a password for AES-256.Faa
How we can compare two hash values with same SALT? Thanks, NehaQuinsy
@Faa Is the password token to be stored on the server side or client side?Carcajou
@ErrolGreen The token is stored at the server, and should be associated with the user identity. For example, a user table with id, login name and/or email address, and token. When someone logs in with login and password, lookup the stored token with the login and pass that to the authenticate() method with the password.Faa
@Faa Sorry to dig up this post, but I spent some time analysing this code. I wonder why in method authenticate(char[] password, String token) you changed if into |= operator? Is there any benefit in this? It looks like only effect will be longer execution time, or I miss something?Penetrance
@TheTosters Yes, the execution time will be longer for incorrect passwords; more specifically, wrong passwords will take the same time as correct passwords. It prevents timing attacks, although I confess I can't think of a practical way to exploit such a vulnerability in this case. But you don't cut corners. Just because I can't see it, doesn't mean a more devious mind won't.Faa
@TheTosters using short-circuit comparison will make it faster, but also make movie-style password cracks possible. The attacker will be able to crack the password one character at a time by observing the time difference in failed auths. This attack is practical on real systems. Time difference is only one example of an oracle permitting faster cryptanalysis. Use validated cryptosystems unmodified and read their usage docs carefully to be confident that you aren’t accidentally breaking them.Monoplane
@Faa Upvotes for you sir and thanks for your patience! I drew boxes as you said, if we copy salt from 0 to salt.length (0 to 1), we copy the byte in hash[0] position. Then we copy dk from salt.length to dk.length - 1 to dk.length we get a correct copy. The base-64 encoding threw me off. When I print the encoded versions, the last char of the salt is gone unless I do +1. With +1 and hash one byte longer: dk: RA, salt: Qw, hash: QwBE. Without +1: and hash one byte smaller: dk: RA, salt: Qw, hash: Q0Q. But we don't need to see Qw and base64 encodes RA and Qw to Q0Q. Cheers and thanks!Dressing
@Dressing That's it. With base-64, each character represents 6 bits of input, so each input byte is sort of smeared out over two characters in the output. Adding one byte of input will either add two characters to the output length (the first byte of a "block"), or modify the last character and add one more (the second and third bytes of a block). But each bit has its place and nothing is lost.Faa
Sir, thanks for this example, can I have a question.. I dont know how to use this class. I first hash password using hash() method, and store it in database with login. Then every time user visits page and wants log in, I use authenticate() method, with input password and hash stored in database.. However every time authenticate() method returns false..Spoon
@Spoon It sounds like you are using it correctly. Can you give an example of a password and the corresponding hash? In addition, here is a sample password and token that you can use for testing: 1ixrvSfjhPqd / $31$16$VKx6w7TTTyO8H504Ajxk6BOW034fSyZYhuayMVsf2P8. Try storing that token in your database and see if you can login then. If so, it suggests that your enrollment process is broken. Of course, if you set that password on an account, the stored token will be different, since a different salt will be used.Faa
@Faa Thanks for help, manually write that token to database, and when input provided password in login, unfortunately same resultSpoon
@Spoon Okay. Do you have a test password and hash for me to test?Faa
@Faa Yes, for example this hash: $31$16$AAnNmTEJQ98dQit8fyv-mMsGul7TFDGXMvE8IgzwqXg , and this password: haslo , I also tried same password with this hash: $31$16$ztuLbvMZjaDgmlsv1gttVZUiLNzvz8uVxb7YcIHpK2oSpoon
@Spoon The authenticate() method returns true when I pass haslo for a password and each of those hashes. Examine the value of your inputs and outputs right at the method, with a debugger or log statements (but don't log passwords in a production system). It looks like something is wrong downstream from the authenticate() call.Faa
@Faa Yes Sir it works :D I dont know what happend, I didnt changed anything in code, only added some system outs prints.. and the next day it suddenly started working! Thank You from a bottom of my heart.Spoon
What is random defined on line 2 of first code block in provided answer? When you provide an answer, could you please elaborate on what you are doing?Quell
@Quell That is meant as a snippet, with a detailed explanation in as following code. Your comment was helpful, but your edit introduced a potential vulnerability by using Random in place of SecureRandom, as demonstrated in the complete example.Faa
T
30

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

Trichroism answered 18/5, 2010 at 20:37 Comment(0)
R
12

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);
Reproach answered 9/3, 2019 at 22:6 Comment(0)
G
9

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.

Genagenappe answered 18/5, 2010 at 20:38 Comment(8)
How would you hash the password at login without storing salt in database?Gorlovka
Using the username as the salt is not a fatal flaw, but it's nowhere near as good as using a salt from a cryptographic RNG. And there is absolutely no problem storing the salt in the database. The salt is not secret.Faa
Wouldn't the username and e-mail also be stored in the database?Korte
@ZZ Coder, @Faa correct, I somehow assumed that it will be one salt for all passwords, which would lead to an easily computable rainbow table.Genagenappe
One problem with using the username (or other ID like email) as a salt is that you can't then change the ID without having the user also set a new password.Dimidiate
Bad idea, you need a salt and work factor. Both are missing from this "protocol".Bulletproof
@MaartenBodewes agreed. Changing the answerGenagenappe
@Faa The salt is not secret if salt is not a secret, wouldn't an attacker who steals the password also steal the salt and simply concatenate it to all passwords that he guesses? What kind of security does the salt add to the whole processes? Please help me understand.Wormwood
C
7

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.

Cookgeneral answered 18/5, 2010 at 21:1 Comment(2)
Thats actually what I was using. But since we decided not to use Shiro, there was some concern about the inefficiency of having to include the whole Shiro library for just that one package.Korte
I don't know of a library made up of just a password hashing utility. You're probably better off rolling your own if dependencies are a concern. The answer by erickson looks pretty good to me. Or just copy the code from that OWASP link I referenced if you'd rather use SHA in a secure manner.Cookgeneral
B
6

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

Balaton answered 14/5, 2012 at 9:14 Comment(1)
it's worth noting that SHA512 isn't better than SHA256 (for this purpose) just because the number is bigger.Desex
O
6

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+).

Oxymoron answered 21/11, 2012 at 7:24 Comment(0)
C
6

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.

Cutty answered 4/7, 2017 at 15:1 Comment(1)
@zaph I edited the answer to be more objective. Please be aware that the NIST recommendation may not always be the best choice (see here for an example) - of course this is true for anything that is recommended somewhere else as well. Therefore I do think this answer provides a value to this question.Cutty
A
5

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.

Airmail answered 14/6, 2020 at 6:42 Comment(1)
I just want to say, this is so well written and it works out of the box like you describe. Thank you.Peptidase
M
3

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

Melitta answered 18/5, 2010 at 20:38 Comment(8)
Just keep in mind that for password hashing, slower is better. You should use thousands of iterations of the hash function as a "key strengthening" technique. Also, salt is imperative.Faa
I was under the impression that multiple iterations of a quality hashing algorithm would produce about the same security as one iteration since the length of bytes would still be the same?Korte
@Faa It would be better to slow down attackers explicitly.Icebox
Yeah, but hashing the hashe's hash ..., is more secure. Let's say you hash "a" to "b" and "b" to "c". Someone could be able to get somehow (though not uniquely) the value "b" but he will unlikely get the original value "a" as he does not know how many times you hashed your intial value.Melitta
@Icebox - "Slow them down explicitly?" What does that mean?Faa
About key strengthening: Salts exist to make precomputed hashes unusable. But attackers do not have to precompute. Attackers can just hash strings + salt "on the fly" until they find the right one. But if you iterate thousands of times for your hashes they will have to do the same. Your server will not be impacted much by 10k iterations as it doesn't happen that often. Attackers will need 10k times the computing power.Nervine
@Melitta today MD5 is considered useless for password hashing as it can be cracked in seconds using GPU brute force / dictionary attacks. See here: codahale.com/how-to-safely-store-a-passwordOxymoron
@zockman you have demystified a concept that had me puzzled ever since I first heard salt and hashing in one sentence. Makes much sense now thanks. +1Wormwood
G
1

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.

Gorlovka answered 18/5, 2010 at 20:43 Comment(3)
Because SSHA doesn't iterate the hash function, it is too fast. This allows attackers to try passwords more quickly. Better algorithms like Bcrypt, PBBKDF1, and PBKDF2 use "key strengthening" techniques to slow attackers to the point where a password should expire before they can brute force even an 8-letter password space.Faa
The problem with all these mechanisms is that you don't get client support. The problem with hashed password is that you can't support password hashed with another algorithms. With ssha, at least all the LDAP clients support it.Gorlovka
It is not "most secure" it is merely "pretty compatible". bcrypt/scrypt are way more ressource intensitive.Rausch
A
0

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);
}






}
Antares answered 30/9, 2019 at 17:9 Comment(1)
I'm open to being corrected, but I think you shouldn't use random numbers when hashing. This is so that your hash function remains deterministic; that is if you hash a string multiple times you will always get the same hash value back for that string.Checker
A
0

Here is my simple PasswordHasher class that I made:

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;

public class PasswordHasher {
    private static final String ALGO = "PBKDF2WithHmacSHA1";
    private static final byte[] SALT = {
            8, 8, 8, 8, 2,
            8, 7, 7, 7, 2,
            1, 1, 1, 1, 2,
            11
    };
    private static final int ITERATION_COUNT = 1000;
    private static final int KEY_LENGTH = 128;

    private SecretKeyFactory mFactory;

    byte[] hashPassword(String password) {
        SecretKeyFactory factory = getFactory();

        if (factory != null) {
            try {
                KeySpec spec = new PBEKeySpec(password.toCharArray(), SALT, ITERATION_COUNT, KEY_LENGTH);
                return factory.generateSecret(spec).getEncoded();
            } catch (InvalidKeySpecException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    boolean verifyPassword(String password, byte[] expectedHashResult) {
        byte[] hashedPassword = hashPassword(password);
        if (hashedPassword == null) {
            // Log fail result
            return false;
        }
        return Arrays.equals(hashedPassword, expectedHashResult);
    }

    private SecretKeyFactory getFactory() {
        if (mFactory == null) {
            try {
                mFactory = SecretKeyFactory.getInstance(ALGO);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        return mFactory;
    }
}
Adrianneadriano answered 7/9, 2022 at 3:15 Comment(0)
I
0
import java.security.MessageDigest;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Base64;
import java.util.Properties;
public class Main{
    public static void main(String[]a]{
    
//enter code here

}
   
    public static String hashPassword(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-512");
            byte[] hash = md.digest(password.getBytes());
            return Base64.getEncoder().encodeToString(hash);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

hashPassword is the method that returns a hashed value when we pass a String as its parameter. MessageDigest is the class that provides the interface for hashing password getInstance is used to get the instance of a hashing algorithm such as MD-5,SHA 216,SHA-512 and so on. The hashed Sting is in the forn of -byte [] In the return statement we convert the byte using ToString.

Infusionism answered 13/2, 2023 at 8:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.