【问题标题】:JPasswordField returning some hash code converted into string typeJPasswordField 返回一些转换为字符串类型的哈希码
【发布时间】:2012-03-27 16:54:25
【问题描述】:

我的程序在初始化程序之前从用户那里获取用户名和密码验证, 所以我创建了一个按钮登录,我将 ActionListener 关联到如下所示

   login.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                if(txtUserName.getText().equals("Suraj") && (txtPwd.getPassword().toString()).equals("s123")){

                                dispose();
                                TimeFrame tFrame = new TimeFrame(userName);
                                tFrame.setVisible(true);
                                tFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                                tFrame.setLayout(new GridLayout());

                        } else {
                            JOptionPane.showMessageDialog(null,"User name or password don't match","Acces Denied", JOptionPane.ERROR_MESSAGE);
                        }

现在出现的问题是即使我输入正确的密码,程序也会显示错误message

【问题讨论】:

  • 任何问题,不知道你的其余代码中隐藏了什么,为我工作,也许更好的方法是阅读getText() vs getPassword()
  • @mKorbel +1 获取可以解释所有问题的链接

标签: java swing jpasswordfield


【解决方案1】:

getPassword() 返回一个char[]。它上面的toString() 不会像您假设的那样将内容作为字符串返回。

试试new String(txtPwd.getPassword()).equals("s123")

但是,它是 char[] 而不是字符串是有原因的。尝试在the javadoc. 中查找它的安全方面

【讨论】:

  • +1,因为使用new String(...),我以为你错过了,所以发布了我的答案,现在删除它,读完那一行:-)
  • 我读到你可以通过使用各自的 toString() 方法将 int 转换为 string 和 char 转换为 string,如果我们无法转换 char 数组,他们为什么还要证明 toString() 方法变成字符串??
  • 正如我在my comment here 中指出的那样,您可以使用“s123”绕过整个安全机制。最好是比较 char 数组
【解决方案2】:

注意:这应该是一个评论,但对于这个来说太长了。考虑为链接线程中的答案投票

正如 mKorbel 已经指出的那样,getText() vs getPassword() 中有一个相当完整的讨论。

进一步,阅读关于JPasswordFieldSwing tutorial,其中包含一个很好的示例,说明您应该如何比较密码(通过比较字符数组,而不是将字符数组转换为String) - 小的复制粘贴来自教程:

private static boolean isPasswordCorrect(char[] input) {
    boolean isCorrect = true;
    char[] correctPassword = { 'b', 'u', 'g', 'a', 'b', 'o', 'o' };

    if (input.length != correctPassword.length) {
        isCorrect = false;
    } else {
        isCorrect = Arrays.equals (input, correctPassword);
    }

    //Zero out the password.
    Arrays.fill(correctPassword,'0');

    return isCorrect;
}

在此答案开头的链接 SO 问题中,Hovercraft Full Of Eels in his answer 很好地解释了您应该比较 char 数组的原因。

【讨论】:

  • 我之前计划实现这个功能,但我想为了节省几行代码,我们可以使用 toString() 方法,它的工作原理和 Johannes 所说的一样
  • @lucifer 使用toString 生成一个以StringPool 结尾的字符串,绕过JPasswordField 中采取的所有安全措施。所以是的,它有效,但它不正确
  • 其实我对java比较陌生,什么是StringPool?我将在java的哪个部分学习这些概念?因为我正在使用 Sun Core java Fundamentals 和 Deital 和 Deital java 如何编程,他们在这些书籍的核心 java 版本中给出的唯一部分是基本的东西,不包括 JVM、StringPool 或安全特性的所有细节,尽管它们注意到当你输入密码时删除字符数组以确保安全关心我将在哪本书中获得这些对java的深刻理解?
  • 我在 [google-interview.com/] 中读到了一些关于 Java 面试的内容,但即使我擅长核心 Java,我也没有理解,但发布的这些面试让我无法​​理解......之后我感觉很糟糕!是否需要一种语言或一种范式的语言能力?
  • @lucifer 不确定哪些书会描述这一点。但是在这个网站上快速搜索字符串池应该会给你足够的信息(例如stackoverflow.com/questions/2486191/java-string-poolstackoverflow.com/questions/2009228/…
【解决方案3】:

我遇到了同样的问题:

private void loginActionPerformed(java.awt.event.ActionEvent evt) {

    char[] pass = passwordField.getPassword();
    String mypass = pass.toString();
    String user = (String) combo.getSelectedItem();


    try {
        String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
        Class.forName(driver);

        String db = "jdbc:odbc:LoginDB";
        con = DriverManager.getConnection(db);
        st = con.createStatement();
        String sql = "select * from Table2";
        rs = st.executeQuery(sql);

        while (rs.next()) {

            String AdminNewID = rs.getString("AdminID");
            String AdminNewPass = rs.getString("AdminPassword");

            if ((user.equals(AdminNewID)) && pass.equals(AdminNewPass)) {

                MyApp form = new MyApp();
                form.setVisible(true);

            } else {
                this.res.setText(" Incorrect User Name or Password");
            }
        }
    } catch (Exception ex) {
    }
}

【讨论】:

  • 请不要以纯文本形式存储密码。请不要吞咽异常。请使用常规命名。
  • 你应该试试这个:new String(txtPwd.getPassword()).equals("YourPassword") 而不是创建你所做的char[] pass = passwordField.getPassword(); String mypass = pass.toString(); 这将比创建一个字符数组对象并创建一个字符串对象更好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
相关资源
最近更新 更多