A previous version of this article confused the process of "hashing" with the process of "encryption". It's worth noting that, while similar, hashi...
For further actions, you may consider blocking this person and/or reporting abuse
A couple comments:
Aside from making sure you're not retaining references to it forever, worrying about trying to overwrite the the String containing the user's password is basically futile. There are likely lots of copies made of that string along the way. If someone has access to your program's memory, it's not protected anyway.
At this point in time, please use argon2 or scrypt as your password hashing algorithm. They force much larger use of memory which makes brute force attack schemes less feasible on GPUs and more expensive on ASICs and FPGUs.
Using a more expensive password hashing scheme should never be a vector for a DoS attack. The correct solution is to implement exponential backoff on repeated failed login attempts: the first failure lets you try again in 100ms, the second failure in 200ms, the third in 400ms, etc. The exception is in environments that specify otherwise, such as health care in the USA, where HIPAA specifies three tries then lockout.
Fair points. Thanks for taking the time to read and comment. These are definitely things I'll have to change if I implement this commercially. (This example was for a term project for a class I took.)
I heard that there's ASIC rigs for mining scrypt
Cool material, very useful!
BTW, thanks for the *Rush * references :)
Just in case someone ever asks me why I refuse to use Java ;)
Very nice article though!
You can use BCrypt in Java as well Hashing passwords in Java with BCrypt.
While this is a well written guide, it should be pointed out that hashing != encryption. Hashing is 1-way, encryption is 2-way. In other words, you can't decrypt a hash, you can only check that rehashing the same value gives the same results.
Thanks for the heads-up! I'm working on an amended version of the article that discusses this issue. I'll post it tonight or tomorrow.
Updated. Let me know what you think!
Looking good!
I've seen the same implementation in PHP done in 3 lines
Yes, most of us agree that dynamically typed languages are easier/faster to code in and generally involve less lines of code But your comment isn't very encouraging, and doesn't add value to this post. Maybe I'm misreading, but it sounds fairly hostile. Do reconsider next time.
If anyone's interested, here are different implementations of this general procedure in languages like PHP, Ruby, JavaScript, and so on. The PHP implementation is indeed just 3 lines:
Yes, I remember because I had to port a similar algorithm in Java and it was like 200 lines of code vs this one!
Could you post it?
Loved reading through some of your articles and have to admit, you have a great style when explaining things. As you have demonstrated to have great coding skills: have you ever worked on WebAuthn / passkeys? How was the developer experience in your opinion?
It's a great idea to toss the password string to the garbage collector ASAP, I've saw a lot of implementation which doesn't consider this fact.
Yeah, unfortunately, there's no way to force garbage collection in Java. You can only suggest it by calling
System.gc()
.Correct. Good article btw, I would probably use the Kotlin/Java implementation of NaCl library but in this case the ones you used are strong enough.
I am try to check the Hashpasword with .equals() method but it is showing stored password and user entered password as false even though both are same please suggest me a code fix. HashedPassword is saving is working fine while registering.
//Java
public boolean userAuthentication(Userdetails userdetails)
{
Optional salt = passwordUtils.generateSalt(CableTVConstants.SALT_LENGTH);
Optional userinfo = userDetailService.findById(userdetails.getUsername());
if(userinfo.isPresent())
{
return passwordUtils.verifypassword(userdetails.getPassword(),userinfo.get().getPassword(),salt.get());
}
logger.log(Level.ALL,"Invalid user credentials");
return false;
}
public boolean verifypassword(String password, String key, String salt)
{
Optional password_check = generateHashPassword(password,salt);
if(!password_check.isPresent())
{
return false;
}
return password_check.get().equals(key);
}
I have a requirement of taking a password from the user and then when he needs to see, then I must decrypt it and show on screen, is this method can be used for decryption.