Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework 2 best way to store password hash of user

I've got an add user option in my app. I'd like to store the user pass in hash format in the database. Th password is stored in plain text format in the sample codes included with the framework. After some searching i've found out that there's a Crypto.encryptAES() function implemented in play2 that can be used to secure passwords.

My question is what's the best place to use it? And how to use it to create the most maintainable code?

like image 991
4spir Avatar asked Mar 27 '13 10:03

4spir


2 Answers

Personally I would do it in the User model. I have getters for my fields, so in setPassword method:

this.password = HashHelper.createPassword(password); 

The Hashhelper is just an singleton class for multi purposes hashing stuff.

And in Hashelper I use BCrypt, just add following to Build.scala

org.mindrot" % "jbcrypt" % "0.3m

And the crypting looks like:

/**
 * Create an encrypted password from a clear string.
 * 
 * @param clearString
 *            the clear string
 * @return an encrypted password of the clear string
 * @throws AppException
 *             APP Exception, from NoSuchAlgorithmException
 */
public static String createPassword(String clearString) throws AppException {
    if (clearString == null) {
        throw new AppException("empty.password");
    }
    return BCrypt.hashpw(clearString, BCrypt.gensalt());
}

And decrypting looks like:

/**
 * Method to check if entered user password is the same as the one that is
 * stored (encrypted) in the database.
 * 
 * @param candidate
 *            the clear text
 * @param encryptedPassword
 *            the encrypted password string to check.
 * @return true if the candidate matches, false otherwise.
 */
public static boolean checkPassword(String candidate, String encryptedPassword) {
    if (candidate == null) {
        return false;
    }
    if (encryptedPassword == null) {
        return false;
    }
    return BCrypt.checkpw(candidate, encryptedPassword);
}

I love to keep my controllers as simple as possible as I see my controllers just as traffic controllers between the user action and the business model (inside my models!) stuff.

like image 179
adis Avatar answered Oct 18 '22 21:10

adis


I found a much simpler solution on the web at this adress : http://rny.io/playframework/bcrypt/2013/10/22/better-password-hashing-in-play-2.html

First download the jbcrypt-xxx.jar at this adress.

In the libraryDependencies in build.sbt, add :

"org.mindrot" % "jbcrypt" % "0.3m"

This is the function to create a new user (located in the model class User) :

  public static User create(String userName, String password) {
    User user = new User();
    user.userName = userName;
    user.passwordHash = BCrypt.hashpw(password, BCrypt.gensalt());
    user.save();
    return user;
  }

And, still in the User class, the function to authenticate :

public static User authenticate(String userName, String password) {
    User user = User.find.where().eq("userName", userName).findUnique();
    if (user != null && BCrypt.checkpw(password, user.passwordHash)) {
      return user;
    } else {
      return null;
    }

And it work !

like image 45
Moebius Avatar answered Oct 18 '22 20:10

Moebius