BCrypt.checkpw not working (Java) - 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).

Related

Storing 1 password in database securely

I have a java swing application which starts with a login page and should take admin to the dashboard if the login is authenticated. As there is just 1 admin, so there is just 1 username and password combination.
Right now, I am just inserting username and password to the sql table using a simple insert query.
I am new at this so I don't know how to go about this
create table login (
Emp_id INT AUTO_INCREMENT PRIMARY KEY,
Emp_Fname VARCHAR(50),
Emp_Lname VARCHAR(50),
Username VARCHAR(50),
Password VARCHAR(50)
);
insert into login (Emp_id, Emp_Fname, Emp_Lname, Username, Password) values (1, 'TestFName', 'TestLName', 'Test', 'Test');
Instead of storing passwords in plain text, I want it encrypted or hash.
I am currently typing from my phone so forgive me. It seems like u want your password to look like: eive29ceic28e8c38d9h3ce9h instead of "password123"
You can use something like SHA-1, which have an integration in java with SHA256 and SHA512. Both of which can be found after a quick Google search. I personally used them in a project but ran recursively this method 100 times using the result from one round as the input for the next. Then I extended the length of the string by using this scheme: password + password backwards + password + password. In my case the password got 4x512 bits long and seemed relatively secure.
After that I saved it to a file and every time I want to login, I take the input and encrypt it and then compare it to my password in my file. If they match you're in. I know that you can crack sha-1 opens it brute force. If you want something different try bcrypt, pbkdf2 or argon2.
I would like to give you links but that's hard on mobile. I hope this works iut for you. Otherwise I will comment tomorrow morning
Edit: look into your comments there is a link to the algorithm I meant. Just put it in a for loop 100 times...

Login Function Improvement and Solve Looping Issue

I am new. Trying to do a database retrieve demo to login a system, here is my function code:
I will call goLogin function and pass in the input id and password for validation and I will also get all the id from Database for checking purpose. After ID is correct, only go check the password.
public void goLogin(String id, String pass){
String[99] allID = getAllIDFromDB();
for(int i=0;i<allID.length;i++){
if(allID[i]==id){
String passwordDB = getPasswordFromDB(id);
if(pass==password){
System.out.println("Correct Password");
}else{
System.out.println("Wrong Password");
}
}
}
My peers say I was using too much if else and I can shorten the code and make the program better, and I faced some issue on looping for example when ID and Password are correct, the program will still continue the loop.
Is there any suggestion to make this function better?
First of all, Why retrieve all the user IDs from the database instead make sql query to retrieve the row of this user based on this id.
something like this:
Select * from `users` where id = {id};
And if you want to stop looping a wrong password was found, add break in the else scope.
In my opinion, the main issue of your program is your logic to implement the Login Function.
Login Function implementation can be implemented with various pattern, Based on your program code I will assume you just want a Most Basic Login Function that allow the program to do validation on user input ID and Password.
Actually, this Basic validation can be done in your Database Query. You can just take the user input ID and Password and let Database Query to do filtering and determine if the user input ID and Password is valid or invalid.
First use this Query:
Select DATABASEID From Database Where DATABASEID=inputID and DATABASEPASSWORD=inputPassword;
Java Code:
public void goLogin(String id, String pass){
// Since i changed the Query, you need to pass in the ID and Password to let the Query to filtering
String DatabaseID = getIDFromDB(id, pass);
// Simple Logic, If DatabaseID have value which mean the ID and Password is correct
// Because the Database Query will return null if the ID and Password is Wrong
if(DatabaseID!=null){
System.out.println("ID and Password is Correct.");
}else{
System.out.println("ID or Password is Incorrect.");
}
}
This Logic is very simple, but also come with some drawback, the only Advantage Compare to your code are:
Still able to do basic validation on User Input ID and Password.
Remove for loop and other unnecessary if else.
Only access database for once.
Hope this would help.
Yes, you could even do:
Select * from `users` where id = {id} and password = {password}
Also, to compare Strings in Java, you should use string1.equals(string2), not the == operator.

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

[Java][SQL] Hardcoded username and password on query

I'm having a problem with my java code. My teacher at university asked me to use "kiuwan" as online code evaluator and he found this problem on my code:
Hardcoded credentials (username / password) are visible to any person reading the source code.
If the resource protected by such hardcoded credentials is important, this may compromise system security.
With hardcoded credentials, change is difficult. If the target account is compromised, and the software
is deployed in production, a code change is needed, which forces a redeployment.
Please note that source code access is not always necessary: if an attacker has access to the JAR file,
he/she may dis-assembly it to recover the password in clear.
And it found this problem on my 3 querys:
public static final String CHECK_USER = "SELECT nome FROM utenti WHERE nome=? AND password=?";
public static final String INSERT_USER = "INSERT INTO utenti (nome, password) VALUES (?, ?)";
public static final String CHECK_USER_NAME = "SELECT nome FROM utenti WHERE nome=?";
How can I fix it? I made them in this way (picking up the info from the textfields) to make the login and check on the database.
Thanks to everyone!
I don't think your teacher is talking about those queries. I think he / she is talking about how your code creates its database connection. He / she has spotted that you have hardwired the user name and password for the database account into your Java code.
A simple solution for this is to read the database account details from a configuration file ... though now you have the problem of keeping the config file secure.
(Why do I think this? Because the text you quoted from your teacher talks about reading a password from the source code or a JAR file ... not from the database.)
For the record, it is also a bad idea to store passwords in the database. But that is not what your teacher is talking about.
Techniques for avoiding storing passwords in the database are more difficult. A typical solution is to create a seeded crypto-hash for the password, and store that in the database. But means that you can't recover the original password. If you need to do that, then things get even more "hairy" ... from a security perspective.

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