我有使用哈希密码的问题。
以下代码尝试通过jsf-Page登录服务器,但是当调用Method登录时,将在底层数据库上更改密码的哈希值。我在9.2版中使用了postgresql数据库 我无法弄清楚为什么。有人可以帮忙吗?
jsf-Page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"` "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF8" />
</h:head>
<body>
<h1>Login</h1>
<div id="container">
<h:form id="create">
<h:commandButton id="create" value="create"
action="#{login.create()}">
</h:commandButton>
</h:form>
<h:form id="loginForm">
<h:panelGrid columns="2">
<h:outputLabel>Username:</h:outputLabel>
<h:inputText value="#{username}" />
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputLabel>Password:</h:outputLabel>
<h:inputText value="#{password}" />
</h:panelGrid>
<h:commandButton id="login" value="Login"
action="#{loginController.login(username, password)}">
</h:commandButton>
</h:form>
<h:form id="response">
<h:panelGrid columns="2">
<h:outputLabel>Response:</h:outputLabel>
<h:outputLabel value="#{login.username}" />
</h:panelGrid>
</h:form>
</div>
</body>
</html>
LoginController:
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.ManagedBean;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import de.lps.entities.User;
import de.lps.server.interfaces.ILPSServerUser;
import de.lps.server.server.LPSServer;
@Named("loginController")
@SessionScoped
public class LoginController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@EJB(beanInterface=ILPSServerUser.class)
private ILPSServerUser server;
private Logger logger;
String username;
public void login(String username, String password) {
this.logger = Logger.getLogger("LoginController");
this.logger.log(Level.INFO, server.toString());
if (username != "" && password != "") {
User user = server.login(username, password);
if (user == null) {
this.logger.log(Level.INFO, "user == null");
this.username = "User N.A";
} else {
this.logger.log(Level.INFO, "got user");
this.username = user.getUserName();
}
} else {
this.logger.log(Level.INFO, "No credentials were given");
this.username = "No credentials were given";
}
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
}
被叫EJB:
package de.lps.server.server;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import de.lps.entities.User;
import de.lps.server.interfaces.ILPSServerUser;
import de.lps.utils.security.PasswordHash;
/**
* Session Bean implementation class LPSServer
*/
@Stateful
public class LPSServer implements ILPSServerUser {
private User loggedUser;
@PersistenceContext
EntityManager em;
Logger logger = Logger.getLogger(LPSServer.class.getPackage().getName());
/**
* Default constructor.
*/
public LPSServer() {
// TODO Auto-generated constructor stub
}
@Override
public User login(String username, String password) {
if (loggedUser == null) {
User user = em.find(User.class, username);
if (user != null) {
if (PasswordHash.comparePasswordWithHash(password,
user.getPassword())) {
loggedUser = user;
logger.log(Level.INFO, "Loggedin successfull | username="
+ username);
return loggedUser;
}
logger.log(Level.WARNING, "GIVEN_PASSWORD_HASH[ "
+ PasswordHash.hash(password)
+ " ] SAVED_PASSWORD_HASH[ " + user.getPassword()
+ " ]");
logger.log(
Level.INFO,
"Not logged in due wrong password| username="
+ user.getUserName());
} else {
logger.log(Level.INFO,
"Not logged in due wrong username| username="
+ username);
}
}
else{
return loggedUser;
}
return null;
}
@Override
public void logout() {
// TODO Auto-generated method stub
logger.log(Level.INFO, loggedUser.getUserName() + " logged out");
this.loggedUser = null;
}
@Override
public void createUser(String username, String password) {
// TODO Auto-generated method stub
User user = new User();
user.setUserName(username);
user.setPassword(password);
em.persist(user);
logger.log(Level.INFO, "User created");
}
}
散列密码的方法:
package de.lps.utils.security;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
public class PasswordHash {
/**
*
* @param password
* @return returns the md5-hash of the password if the password == null returns null
*/
public static String hash(String password){
if(null == password){
return null;
}
MessageDigest sha256;
try {
sha256 = MessageDigest.getInstance("SHA-256");
byte[] passBytes = password.getBytes("UTF-8");
byte[] passHash = sha256.digest(passBytes);
return DatatypeConverter.printHexBinary(passHash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
/**
* Compares a specified password with a specified hash
* @param password
* @param hash
* @return return true when hash and password are equals
*/
public static boolean comparePasswordWithHash(String password, String hash){
if(hash(password).equals(hash)){
return true;
}
return false;
}
}
实体用户:
package de.lps.entities;
import java.io.Serializable;
import java.lang.String;
import javax.persistence.*;
import de.lps.utils.security.PasswordHash;
/**
* Entity implementation class for Entity: User
*
*/
@Entity
@Table(name = "lps_user")
public class User implements Serializable {
private String userName;
private String password;
private static final long serialVersionUID = 1L;
public User() {
super();
}
@Id
@Column(name = "username")
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name = "password", length=1000)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = PasswordHash.hash(password);
}
}
感谢您的帮助,并为我糟糕的英语技能感到抱歉
答案 0 :(得分:3)
这是因为当您尝试从数据库加载User
实例时,EntityManager
将使用User#setPassword(String)
setter来设置它获得的password
的值从你的桌子。这将重新计算密码哈希值,因此您不会使用原始哈希值,而是哈希值的哈希值。
您应该在您的setter方法之外哈希密码。