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
}
Related
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...
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).
I am currently developping a java program coupled with a mysql database using the Dao pattern. I have some user info to be stored in a table and I am storing a Sha1 hashed version of the original password string. I am using apache.commons.codec.digest.DigestUtils to do that. The string displayed in php-mysql is perfect, but when I am trying to display the same string in a java test program I have a completely different result.
Here is my constructor for the user object :
public User(int id, String name, String firstName, String email, String login, String password)
{
super(id, name, firstName);
this.email = email;
this.login = login;
//Convert the password to SHA1 before storing it in the object
//using Apache commons-codec-1.9 lib
this.hashedPassword = DigestUtils.sha1Hex(password);
}
So for example when creating a User with "aff" as the password,
by
User user1 = new User(1, "Durand", "Jack", "jack.durand#mymail.com", "jack", "aff");
I get
"0c05aa56405c447e6678b7f3127febde5c3a9238" in mysql which looks correct, and the same as the output of online sha1 hashers.
But when reading the data back into an object and displaying it by a Sysout(User.getPassword()) in java I get
"c14b77e8930a8bfd884c8917f2b7335501a39dde" which obviously isn't the same.
Any idea of what's causing this? I have read some previous posts about a Byte[] issue, but the DigestUtils.sha1Hex(password) method is said to return a plain String. So what am I missing?
Everything you did is correct.
"0c05aa56405c447e6678b7f3127febde5c3a9238" is the correct output.
I would suspect MySQL is being updated between reads.
My suggestion would be, check if the value "0c05aa56405c447e6678b7f3127febde5c3a9238" is actually being saved to MySQL. Break the workbench open and access the row to check its value.
If the value in MySQL is correct then it is in the transformation from RDBMS -> Java. If you defined the attribute password as a String then Hibernate (or whatever you are using) should leave the field as is.
I have domain with 3 field cardNo, cardName and account
class card {
String cardNo
String cardName
Account account
static constraints = {
cardNo(blank:false, unique:true)
cardName(blank:false)
account(blank:false)
}
The cardNo must be encrypted when saved, I used encryptionUtil Java to encrypt it.
On my list screen, I want to make search fiture, which can be search by cardNo and cardName.
Is it possibe if I search data encrypted with create cretiria in grails??
If can't use create criteria, what is the best way to search encrypted data??
Need your help. thanks before :)
I can give you an advice: avoid store card numbers in your database. Use payment services for it.
I have a simple setup with an app server backed on to CouchDB in which I'm using CouchDB's built-in user authentication for users of the app server. The app server can access the _users database and retrieve a user's doc.
I am trying to replicate the password hash function so I can validate a user's password in the app server without having to authenticate against CouchDB.
The CouchDB security spec states:
The "password_sha" attribute is an hexadecimal representation of the SHA-1 hash computed over a string that matches the user password concatenated with a salt (ideally a random string). The salt attribute is the hexadecimal representation of the salt used to generate the user's password hash.
Since CouchDB 1.2.0, the password_sha and salt fields are automatically created when a password field is present in the user document. When the user document is written, CouchDB checks for the existence of the password field and if it exists, it will generate a salt, hash the value of the password field and hash the concatenation of the password hash and the salt. It then writes the resulting password into the password_sha field and the salt into the salt field. The password` field is removed.
Relevant source code:
% Lines 72-74 of couch_httpd_auth.erl
UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<>>),
PasswordHash = hash_password(?l2b(Pass), UserSalt),
ExpectedHash = couch_util:get_value(<<"password_sha">>, UserProps, nil),
% Lines 237-238 of couch_httpd_auth.erl
hash_password(Password, Salt) ->
?l2b(couch_util:to_hex(crypto:sha(<<Password/binary, Salt/binary>>))).
This is my attempt to replicate it with a test user that has a password of "password":
import java.security.MessageDigest
import org.apache.commons.codec.binary.Hex
import org.specs2.mutable.Specification
class PasswordSpec extends Specification {
"Password" should {
"match" in {
val password = "password"
val hexEncodedPasswordHash = "0fed560a9928b50761ebec5aa97c815999e6def0"
val hexEncodedSalt = "2ba345d5f2880fae25de9ec7a78d38ae"
val charset = "UTF-8"
val codec = new Hex(charset)
val md = MessageDigest.getInstance("SHA-1")
md.reset()
md.update(password.getBytes(charset))
md.update(codec.decode(hexEncodedSalt.getBytes(charset)))
val hashBytes = md.digest()
val hexEncodedHash = new String(codec.encode(hashBytes), charset)
hexEncodedHash mustEqual(hexEncodedPasswordHash)
}
}
}
This test is failing and I've run out of ideas as to why.
I figured it out. The salt bytes do not need to be decoded from hex before being concatenated with the password bytes.