0

我有一个 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;
}
4

1 回答 1

2

如果用户名是敏感的;

  • Hash the username with a static salt (single salt for the system, but should be enough to protect the username)
  • Hash the password with a dynamic salt (individual for every user) that is saved along with the password in the database.

When a user tries to log in;

  • Hash his username given at login using the static salt and search for the result in the database. This will be an exact match search that will give a single result (or none if the username does not exist)

  • Get the dynamic salt from the found row, and hash his password given at login using it. If it matches the hashed password in the found database row, let the user in.

Given this security, no one (not even you) can list all user names in the system. If you know a user name, you can verify its existence and find the user.

于 2013-07-14T18:02:31.400 回答