优化JSF+JPA web应用程序中的身份验证



我有一个JSF+JPA web应用程序,其中的登录机制如下。

  1. 用户名已加密
  2. 密码被哈希
  3. 二手Jasypt
  4. 当用户尝试登录时,所有用户都会进入一个循环
  5. 每个用户的用户名都会被解密,并与输入的用户名相匹配
  6. 如果匹配,则对密码进行散列处理,并使用存储的hased密码进行检查

在另一个用户数量预计很高的应用程序中,我从前三个字母中筛选用户,这三个字母存储为一个单独的字段。

如果你能指出我使用的次优方法并指导我采取正确的行动,我将不胜感激。

与加密有关的控制器列为

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.jasypt.util.password.BasicPasswordEncryptor;
import org.jasypt.util.text.BasicTextEncryptor;

@ManagedBean
@SessionScoped
public class SecurityController implements Serializable {
    private static final long serialVersionUID = 1L;

public SecurityController() {
}
public String encrypt(String word) {
    BasicTextEncryptor en = new BasicTextEncryptor();
    en.setPassword("health");
    try {
        return en.encrypt(word);
    } catch (Exception ex) {
        return null;
    }
}
public String hash(String word) {
    try {
        BasicPasswordEncryptor en = new BasicPasswordEncryptor();
        return en.encryptPassword(word);
    } catch (Exception e) {
        return null;
    }
}
public boolean matchPassword(String planePassword, String encryptedPassword) {
    BasicPasswordEncryptor en = new BasicPasswordEncryptor();
    return en.checkPassword(planePassword, encryptedPassword);
}
public String decrypt(String word) {
    BasicTextEncryptor en = new BasicTextEncryptor();
    en.setPassword("health");
    try {
        return en.decrypt(word);
    } catch (Exception ex) {
        return null;
    }
    }
}

这是我检查停用的方法。

private boolean checkUsers() {
    String temSQL;
    temSQL = "SELECT u FROM WebUser u WHERE u.retired = false";
    List<WebUser> allUsers = getFacede().findBySQL(temSQL);
    for (WebUser u : allUsers) {
        if (getSecurityController().decrypt(u.getName()).equalsIgnoreCase(userName)) {
            if (getSecurityController().matchPassword(passord, u.getWebUserPassword())) {
                setLoggedUser(u);
                setLogged(Boolean.TRUE);
                setActivated(u.isActivated());
                setRole(u.getRole());
                getMessageController().setDefLocale(u.getDefLocale());
                getMeController().createMenu();
                getWebUserBean().setLoggedUser(u);
                UtilityController.addSuccessMessage("Logged successfully");
                return true;
            }
        }
    }
    return false;
}

如果用户名是敏感的;

  • 使用静态salt对用户名进行散列(系统使用单个salt,但应该足以保护用户名)
  • 使用动态salt(每个用户单独使用)对密码进行哈希,该salt与密码一起保存在数据库中

当用户尝试登录时;

  • 使用静态salt对登录时给出的用户名进行散列,并在数据库中搜索结果。这将是一个完全匹配的搜索,将给出一个结果(如果用户名不存在,则无结果)

  • 从找到的行中获取动态salt,并使用它对登录时给出的密码进行哈希。如果它与找到的数据库行中的哈希密码匹配,则让用户进入。

考虑到这种安全性,没有人(甚至你)可以列出系统中的所有用户名。如果你知道一个用户名,你可以验证它的存在并找到用户。

相关内容

最新更新