5

I am currently creating application using Java, I googled password encryption with java but the results are so enormous I felt overwhelmed. How would I encrypt and decrypt a password using Java? And what is the best practice for encrypting and decrypting passwords? I am guessing MD5 is not a way to go since it is a one way hash. I am using struts2 as my framework, was wondering if they provide password encryption

5
  • 5
    I strongly recommend you to use one way hash algorithm, rather than which can be decrypted. Due to various security reasons, one way hash is best. Commented Dec 26, 2012 at 14:34
  • 1
    You wouldn't encrypt and decrypt passwords because it's two-way. You would salt and hash them, precisely because it's one-way, and thus no-one could ever go back to the original password by having the hashed one. Use bcrypt. Commented Dec 26, 2012 at 14:35
  • Do you really need to encrypt the passwords? Is hashing not possible in your scenario? And where does your key come from? A master password entered by the user? Commented Dec 26, 2012 at 14:54
  • 1
    MD5 is no loger a secure one-way hash (en.wikipedia.org/wiki/MD5) Commented Dec 26, 2012 at 16:18
  • @MrSmith42 The one-wayness(first pre-image) of MD5 is still quite strong. It's collisions that are weak, but those don't apply to password hashing. While it's better to use something else, the cryptographic weakness of MD5 isn't of immediate concern for password hashing. It's far more important to choose a good strengthening scheme than choosing SHA-2 over MD5. Commented Dec 26, 2012 at 17:11

6 Answers 6

7

Updated:

Try JBCrypt:

String password = "MyPassword123";
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
System.out.println(hashed);  // $2a$12$QBx3/kI1SAfwBDFOJK1xNOXK8R2yC7vt2yeIYusaqOisYbxTNFiMy

Download jBCrypt-0.3 from here, check README file for more details.

Sign up to request clarification or add additional context in comments.

5 Comments

The new code might fool a reader into thinking that a constant value is good salt (a common misunderstanding), so I won't rescind my downvote unless you replace it with a decent salt generation code. And you're still using a fast hash, which is downvote worthy on its own.
@CodesInChaos: What do you mean by fast hash?
Any general purpose hash with a single iteration (MD5, SHA-x,...) is too fast. You should use a deliberately expensive construction, such as bcrypt, scrypt or at least PBKDF2.
Thanks @CodesInChaos this was a gr8 lesson. I have also found an interesting post on hacker news
Choosing between scrypt, bcrypt and PBKDF2 is situation dependent, but all of them are much better than most homebrew solutions. Your new bcrypt code seems fine.
4

Also I don't recommend to use MD5 because, it's already broken. Instead of that you can use SHA512 it's secure hashing method, you can use MessageDigest. Below code I am using in one of my project, which works perfectly

public String encode(String password, String saltKey)
        throws NoSuchAlgorithmException, IOException {

    String encodedPassword = null;
    byte[] salt = base64ToByte(saltKey);

    MessageDigest digest = MessageDigest.getInstance("SHA-512");
    digest.reset();
    digest.update(salt);

    byte[] btPass = digest.digest(password.getBytes("UTF-8"));
    for (int i = 0; i < ITERATION_COUNT; i++) {
        digest.reset();
        btPass = digest.digest(btPass);
    }

    encodedPassword = byteToBase64(btPass);
    return encodedPassword;
}

private byte[] base64ToByte(String str) throws IOException {
    BASE64Decoder decoder = new BASE64Decoder();
    byte[] returnbyteArray = decoder.decodeBuffer(str);
    if (log.isDebugEnabled()) {
        log.debug("base64ToByte(String) - end");
    }
    return returnbyteArray;
}

11 Comments

Insecure: you're not salting the password, and buggy: you rely on the default platform encoding.
Any reason why you use a homebrew iterated scheme over PBKDF2 or bcrypt? - Another issue is that your code is very incomplete. For example it doesn't show salt creation or how verification would work.
@CodesInChaos..salt creation is unique to the type of problem OP is trying to solve, he/she can generate salt based on his preferences, that's why I haven't shown
From the salted password, how would I compare it to user input? do I have to encrypt it again? and please provide a sample for salt.
@user962206 It's a constant that should be at least 10000. Or even larger if you can afford the higher computational effort.
|
0

well, as I know we have following some algorithm to secure password.

  1. MD5 -
  2. PBKDF2 -
  3. SHA -
  4. BCrypt and SCrypt -

among this BCrypt and SCrypt are the more secure way for password security.

Comments

-1

There is quite nice project dedicating to solving that problem in Java. Essentially, it provides two ways of encrypting user passwords: - MD5
- SHA1

Take a look to the link: jasypt

2 Comments

This is worse that a link only answer, since your summary is very badly written.
You may also want to update your answer with some better terminology. Hashing != encrypting; encryption is reversible.
-2

for me i see that MD5 its the best way and you don't need to decrypt the password in case the user forgot his password you can give him a way to generate a new one and for the log in you can compare just the hash existing in the data base and the one entred by the user

4 Comments

MD5 is not the best way. Actually, MD5 should no longer be used to hash passwords. Use a stronger hashing algorithm instead.
you just saying that MD5 is not the best way and you did not give a solution ??
@haffanehatim Because the problem has been discussed to death. As always, use bcrypt, scrypt or PBKDF2 with a unique per-user salt. No general purpose hash(including MD5 and SHA-2) should be used directly to hash passwords.
@haffanehatim He is commenting on your answer, not providing an answer of his own. His comment is correct. It is not necessary to lay an egg yourself in order to detect a rotten one laid by someone else.
-3

Always use ONE WAY HASH ALGORITHM.

I would say GO with MD5 hashing. While storing password in DB, use MD5 hashing. So that if you have your password as pass, after hashing it will get stored as asjasdfklasdjf789asdfalsdfashdflasdf (32 character).

As you said, you want to de-crypt the password also. I would say don't do that. While checking the password against DB, what you can do is hash the password and compare that string with what you have in database.

if (DoHashMD5(myPass).equals(rs.getString(2))) {
    System.out.print("You are registered user!!!");
} else {
    System.out.print("Invalid user!!!");
}

here rs.getString(2) would be your query parameter.

3 Comments

A one-way hash without salt is very insecure, because vulnerable to rainbow table attacks.
@JBNizet : I agree to some point, BUT I would say, HASHING itself even is not secure. Have a look at my question
@FahimParkar: Err, that's precisely what I'm saying: a hash without salt is very insecure. And that's why I recomment bcrypt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.