Compares password from DB (encoded password) and user entered [duplicate] - java

This question already has answers here:
Getting same hashed value while using BCryptPasswordEncoder
(2 answers)
Closed 7 years ago.
How to compare password entered by user and saved in DB using BCryptPasswordEncoder.
Below is the code we are using to save password in DB:
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String password = encoder.encode("Test"));
DB.save(password);
How to check user entered password and above saved password to allow login?
Any suggestions or links which explains above procedure will be of great help?

Assuming your encoding method will give the same value each time you encode a given string, then:
Look up the user by username.
Encode the password they typed in, store in memory.
Check the encoded value with the value in the Database. If it matches, then they typed the right password. If it doesn't match, then they didn't.

Related

JPA Repository & Spring Security - updating object makes password invalid

I'm trying to update a field of my user DTO, but every time I update by doing userService.save(user), my login credentials become invalid in the database, because when I first get the user I get the encrypted password in the password field of my DTO, and when I save the user again I'm re-encrypting the encrypted password making the password different than before.
How can I go about fixing this? Should I decrypt the password when I first query the database in my user service? Is that safe?
Edit : found out you can't decode the password (I'm using BCryptPasswordEncoder) anyways. Is there a way to update all my fields without affecting the password?
Have you tried to update only the column without saving the entire entity?
There is an example of how to create such a query in the Spring Data JPA documentation:
https://docs.spring.io/spring-data/jpa/docs/2.1.1.RELEASE/reference/html/#jpa.modifying-queries
Addition:
If there is a way to save only the password without re-encrypting it? If so, you could perhaps try to:
- Obtain the encrypted password.
- Update the user entity (resulting in the encrypted password being encrypted a second time).
- Overwrite only the password in the user with the encrypted password obtained in step 1.
You should use entity listeners.
Look here https://www.concretepage.com/java/jpa/jpa-entitylisteners-example-with-callbacks-prepersist-postpersist-postload-preupdate-postupdate-preremove-postremove
Create entity listener class, implement preUpdate method.
You should inject applicationContext into class. You can find bean "passwordEncoder". Spring use it to encode password.
In pre update method you get your raw password, create encoded version like
passwordEncoder.encode(password) and set it back to the entity.

How to check if value is correct for key in HashMap in Java

I'm writing a simple GUI program where I have to input login and password for user and then check if he is in database (my Hashmap). That's where i have problem. I checked if login is correct by containsKey and checked for password by containsValue. The problem is, that if in example I have 2 users:
login: user1 password: example
login: user2 password: programing
If I put login as user1 in my JTextField and password "programing", the program says, that it's correct.
That's where I have a problem. How to check the password for exact login, which is key?
Would be very thankful for any clues or solutions :)
You can use a check like this:
if(userEnteredPassword.equals(hashMap.get(userEnteredUsername))){
// Correct credentials.
.....
}
It's important to use userEnteredPassword.equals.... instead of hashMap.get(userEnteredUsername).equals... because you'll get a null pointer exception if there is no map entry for userEnteredUsername

BCrypt.checkpw not working (Java)

My web app uses BCrypt to encrypt user password and save it to MySQL (column data type: varchar(255))
BCrypt.hashpw(password, BCrypt.gensalt(15));
However, when the user logins, the BCrypt.checkpw fails to match the password that is the same as the one used in registration (before hashing).
boolean passwordMatch = BCrypt.checkpw(password, user.getPassword()); //false
I don't know what's happening. Does anyone have an idea where I should check?
I just found out that it doesn't seem having anything to do with BCrypt, because I tried to recompile my web app, and the login works, however, I don't understand why it requires a recompile though.
BCrypt.hashpw(password, BCrypt.gensalt(15));//this is when you insert
//********
boolean passwordMatch = BCrypt.checkpw( plainPassword , myPasswordOnDB);
(plainPassword is the String password and myPasswordOnDB is the encrypted password)
This is the right way of checking a password. If that doesn't work for you try making the mySQL column password char(60).

substring and substr php to java

Hi I am currently trying to link a java application I am making to a website I have. Basically I want the accounts that are made on the site to be accessible on the java app. on my login page I have a block of code that extracts a part of the password saved in the sql database. Here it is:
$username = $_POST['username']; //gets the username that is posted from the login page
$password = hash(sha256, md5(sha1($_POST['password']))); //encrypts the password posted from the login page
//get the requested user's password
$details = $database->processQuery("SELECT `password` FROM `users` WHERE `username` = ?", array($username), true); //gets the password from the sql database
$db_password = substr(substr($details[0]['password'], 54), 0, -3); //extracts characters from the saved password from 54 to -3 from the end
In the register page I have this:
//generate a salt
$salt = substr(hash(sha256, sha1(time())), 10);
$password = $salt.hash(sha256, md5(sha1($_POST['password']))).substr($salt, 0, -51);
$_SESSION['salt'] = $salt;
$_SESSION['password'] = $password;
$base->redirect('done.php');
I believe this adds the salt before the password that is generated by the time. So I need to extract JUST the password and obviously in the login page it is able to do this by starting the password at 54 and ending it 3 characters before the end. I have made an cryptographer that encrypts the password the user enters in the java application (sha1 > md5 > sha254) then I tried to match the passwords. I used:
substring(54, pass.length()-3)
This worked perfectly with a randomly generated password I entered on the website "d1ck30ng1". But when I made another account with the password "test123" I get an extra character before the password that matches it here is an example:
d1ck30ng1:
Password that is read from the database before parts are removed:
5a3a59efb7d2085d12a2fe5298a7795c85b99dc7b3bcabc60d9e4c6469fe4370d1bd7f2b4ff0151698e3911a97f326f1fc1409a8d5430e7d283cbf5a3
Password that is entered in the application:
6469fe4370d1bd7f2b4ff0151698e3911a97f326f1fc1409a8d5430e7d283cbf
Password that is read from the database after the parts are removed:
6469fe4370d1bd7f2b4ff0151698e3911a97f326f1fc1409a8d5430e7d283cbf
matches perfectly
test123:
Password that is read from the database before parts are removed:
fb1c94c4ab1b104badff98261269856aca8d34575c7114124aebbd068dc28e9d998bee17cdb25f5b1501710d4a629ad37f762478eeb01f465bc24bfb1
Password that is entered in the application:
68dc28e9d998bee17cdb25f5b1501710d4a629ad37f762478eeb01f465bc24b
Password that is read from the database after parts are removed
068dc28e9d998bee17cdb25f5b1501710d4a629ad37f762478eeb01f465bc24b
does not match!
So my question is... How can i get this to work and why isn't it working :) Thank you in advance! Oh and by the way, I'm new here so I'm sorry if I didn't put enough detail into this post or have done something wrong while posting.

matching user's password from record in db

In my web app which uses servlets and hibernate. I need to authenticate a Customer who enters a password.
If he is already in database, I need to check if his password matches that of the record in db.For a new Customer, I want to take a password and create a record for him.
I tried to do it this way for the scenarios.
Existing Customer enters an emailAddress and password
String email = req.getParameter("emailAddress");
String password = req.getParameter("password");
Customer cust = dao.findByEmailAddress(email);
Now, how do I check if this cust object is associated with a password and that matches what the user entered? Manning's hibernate book example stores password as a String in Customer class. Is this a good idea? How will this be stored in database?
When using hibernate, how can this be handled? I have heard people mentioning about storing passwords as hash. But I am not very sure how I can do this in my app.
Can someone tell me how I can tackle this?
Storing plain text passwords is never a good idea. In fact it is listed as #8 threat in the Top 25 Most Dangerous Software Errors.
You need to encrypt the passwords before writing them in the database. When searching for a user use the encrypted password
String email = req.getParameter("emailAddress");
String password = req.getParameter("password");
String encryptedPassword = MD5Helper.hashPassword(password)
Customer cust = dao.findByEmailAddressAndPassword(email, encryptedPassword);
You can use something like this to encrypt the passwords using the MD5 algorithm.
public class MD5Helper {
private static final int MD5_PASSWORD_LENGTH = 16;
public static String hashPassword(String password) {
String hashword = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(password.getBytes());
BigInteger hash = new BigInteger(1, md5.digest());
hashword = hash.toString(MD5_PASSWORD_LENGTH);
} catch (NoSuchAlgorithmException nsae) {
// handle exception
}
return hashword;
}
}
You have to decide how to store passwords. If you store them as a String in a Hibernate entity, they will be stored in a varchar in database, in clear text. Anyone having access to the database will thus be able to see them. Authenticating in this case consists in comparing the sent password with the one in database.
There are two other possibilities
The first one consists in encrypting them with a secret key before storing them in database. But this secret key will have to be stored somewhere in order for your application to decrypt them and compare the decrypted password with the one sent by the user. But it could at least reduce the visibility of the password only to the persons having acces to the application deployment directory. Authenticating in this case consists in decrypting the password stored in database with the secret key, and compare it with the password sent by the user. If they are equal, then the user sent the correct password.
The last possibility would be to use a one-way hash algorithm (like SHA-1, for example), also known as message digest algorithm. This way, there is no need for a secret key, and it would be very hard (read : nearly impossible) for anyone to get access to the password (if the password is salted). The drawback of this solution is that if a user looses his password, you won't be able to send him. The only possibility is to reset him to a new value, send this new password to the user and ask him to choose a new one. Authenticating the user, in this case, consists in hashing the password he sends and comparing with the hash stored in database.
Read http://en.wikipedia.org/wiki/Salt_(cryptography) for more detailed explanations.
Usually password are stored encrypted in a database and you have to encrypt the input password to check if it matches.
String passwordEncrypted = encrypt(password);
where encrypt is your function that crypt the password (you can try with MD5 or SHA-1, for example).
After you've retrieved your object cust, you can check if
if (cust.getPassword().equals(passwordEncrypted)) {
// login successfull code
} else {
// login failed code
}

Categories

Resources