我的应用程序中有一个添加用户选项。我想将用户传递以哈希格式存储在数据库中。密码以纯文本格式存储在框架附带的示例代码中。经过一番搜索,我发现在 play2 中实现了 Crypto.encryptAES() 函数,可用于保护密码。
我的问题是使用它的最佳位置是什么?以及如何使用它来创建最可维护的代码?
我的应用程序中有一个添加用户选项。我想将用户传递以哈希格式存储在数据库中。密码以纯文本格式存储在框架附带的示例代码中。经过一番搜索,我发现在 play2 中实现了 Crypto.encryptAES() 函数,可用于保护密码。
我的问题是使用它的最佳位置是什么?以及如何使用它来创建最可维护的代码?
我个人会在User
模型中这样做。我的领域有吸气剂,所以在setPassword
方法中:
this.password = HashHelper.createPassword(password);
这Hashhelper
只是一个用于多用途散列的单例类。
在 Hashelper 中我使用 BCrypt,只需将以下内容添加到 Build.scala
org.mindrot" % "jbcrypt" % "0.3m
加密看起来像:
/**
* 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());
}
解密看起来像:
/**
* 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);
}
我喜欢让我的控制器尽可能简单,因为我将控制器视为用户操作和业务模型(在我的模型内部!)之间的流量控制器。
我在这个地址的网上找到了一个更简单的解决方案: http ://rny.io/playframework/bcrypt/2013/10/22/better-password-hashing-in-play-2.html
首先在这个地址下载jbcrypt-xxx.jar 。
在 build.sbt 的 libraryDependencies 中,添加:
"org.mindrot" % "jbcrypt" % "0.3m"
这是创建新用户的函数(位于模型类用户中):
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;
}
而且,仍然在 User 类中,验证功能:
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;
}
它工作!