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
-
5I 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. – Pradeep Simha Dec 26 '12 at 14:34
-
1You 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](http://en.wikipedia.org/wiki/Bcrypt). – JB Nizet Dec 26 '12 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? – CodesInChaos Dec 26 '12 at 14:54
-
1MD5 is no loger a secure one-way hash (http://en.wikipedia.org/wiki/MD5) – MrSmith42 Dec 26 '12 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. – CodesInChaos Dec 26 '12 at 17:11
6 Answers
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.

- 21,044
- 23
- 95
- 105
-
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 Dec 26 '12 at 15:43
-
-
2Any 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. – CodesInChaos Dec 26 '12 at 16:08
-
Thanks @CodesInChaos this was a gr8 lesson. I have also found an interesting post on [hacker news](http://news.ycombinator.com/item?id=3724560) – tokhi Dec 26 '12 at 16:48
-
1Choosing 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. – CodesInChaos Dec 26 '12 at 17:08
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;
}

- 106,488
- 23
- 218
- 262

- 17,683
- 18
- 56
- 107
-
Insecure: you're not salting the password, and buggy: you rely on the default platform encoding. – JB Nizet Dec 26 '12 at 14:44
-
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 Dec 26 '12 at 14:58
-
@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 – Pradeep Simha Dec 26 '12 at 15:35
-
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 Dec 26 '12 at 15:47
-
@user962206 1)salt and hash the password and store it in db 2) everytime user logins hash and salt the password and compare it with hashed and salted password in DB 3) if both matches then login is success. – Pradeep Simha Dec 26 '12 at 15:51
-
@user962206 with respect to salting, this thread gives you idea http://stackoverflow.com/questions/1884598/what-is-the-purpose-of-the-salt-when-hashing – Pradeep Simha Dec 26 '12 at 15:51
-
How do I salt and hash a password? do I just immediately parse or concatenate it to the string password? – user962206 Dec 26 '12 at 15:52
-
@user962206 you need not do anything, just pass salt as an argument to above code, it will work fine.. :) digest.update(salt); this line will take care of it – Pradeep Simha Dec 26 '12 at 15:58
-
-
@user962206, oops! sorry I haven't mentioned in my answer. It's how many times you need to perform hashing. – Pradeep Simha Dec 26 '12 at 17:05
-
2@user962206 It's a constant that should be at least 10000. Or even larger if you can afford the higher computational effort. – CodesInChaos Dec 26 '12 at 17:12
well, as I know we have following some algorithm to secure password.
- MD5 -
- PBKDF2 -
- SHA -
- BCrypt and SCrypt -
among this BCrypt and SCrypt are the more secure way for password security.

- 41
- 6
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

- 19
- 2
-
1This is worse that a link only answer, since your summary is very badly written. – CodesInChaos Dec 26 '12 at 15:01
-
You may also want to update your answer with some better terminology. Hashing != encrypting; encryption is reversible. – Greg Dec 26 '12 at 21:33
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

- 474
- 5
- 30
-
1MD5 is not the best way. Actually, MD5 should no longer be used to hash passwords. Use a stronger hashing algorithm instead. – Pablo Dec 26 '12 at 14:58
-
you just saying that MD5 is not the best way and you did not give a solution ?? – haffane hatim Dec 26 '12 at 17:11
-
1@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. – CodesInChaos Dec 26 '12 at 17:13
-
@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. – user207421 Dec 31 '12 at 07:31
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.

- 30,974
- 45
- 160
- 276
-
1A one-way hash without salt is very insecure, because vulnerable to rainbow table attacks. – JB Nizet Dec 26 '12 at 14:47
-
@JBNizet : I agree to some point, BUT I would say, HASHING itself even is not secure. Have a look at [my question](http://stackoverflow.com/questions/13323167/is-hashing-mechanism-really-secure) – Fahim Parkar Dec 26 '12 at 14:51
-
@FahimParkar: Err, that's precisely what I'm saying: a hash without salt is very insecure. And that's why I recomment bcrypt. – JB Nizet Dec 26 '12 at 14:58