如何在不使用System.console()的情况下从控制台读取密码?

时间:2013-03-01 14:13:29

标签: java security console passwords

我点击this eclipse bug,其中System.console()无法用于Java应用程序启动。我有一个小型Java应用程序,它还需要输入一个只能在IDE中启动的密码。有没有其他方法安全从控制台读取密码(意味着不在控制台上显示)只使用JDK类?

修改
我知道System.in,但这是在控制台中显示输入的字符,因此不安全。

EDIT2:
我还想注意,可以在windows下创建一个批处理文件,或者在项目中的linux / unix下创建一个小的bash脚本。通过使用系统默认编辑器在eclipse中打开此文件,它将在System.console()可用的新控制台窗口中启动。这样你就可以在eclipse中启动应用程序。但是必须首先构建项目,以便存在二进制文件。

4 个答案:

答案 0 :(得分:3)

也许不使用控制台尝试使用JPasswordField对话框。以下是http://blogger.ziesemer.com/2007/03/java-password-dialog.html的示例。

final JPasswordField jpf = new JPasswordField();
JOptionPane jop = new JOptionPane(jpf, JOptionPane.QUESTION_MESSAGE,
        JOptionPane.OK_CANCEL_OPTION);
JDialog dialog = jop.createDialog("Password:");
dialog.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentShown(ComponentEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                jpf.requestFocusInWindow();
            }
        });
    }
});
dialog.setVisible(true);
int result = (Integer) jop.getValue();
dialog.dispose();
char[] password = null;
if (result == JOptionPane.OK_OPTION) {
    password = jpf.getPassword();
}
if (password != null)
    System.out.println("your password: " + new String(password));

答案 1 :(得分:3)

如果System.console()返回null,则表示就Java而言,没有可用的控制台。

  • 您无法使用System.in,因为它可能无法连接到控制台。

  • 即使你可以,也没有可移植的方式来关闭Java中的回显。

  • 您可以使用Swing(或其他)弹出一个窗口来询问密码,但是如果系统无头无法工作。


如果您准备做不便携的事情,那么(在Linux / UNIX上)您可以尝试打开" / dev / console"或" / dev / tty"。然后你可以使用termios将tty驱动程序置于noecho模式。但是你需要在本机代码中至少完成其中的一部分。

答案 2 :(得分:3)

我遇到了同样的问题。 (亲爱的Eclipse社区:修复那个bug真的很难吗?) 和其他人一样,我需要IDE用于开发/调试和独立运行。

所以我写了这个方法:

private static String readPwd() throws IOException {
    Console c=System.console();
    if (c==null) { //IN ECLIPSE IDE
        System.out.print("Password: ");
        InputStream in=System.in;
        int max=50;
        byte[] b=new byte[max];

        int l= in.read(b);
        l--;//last character is \n
        if (l>0) {
            byte[] e=new byte[l];
            System.arraycopy(b,0, e, 0, l);
            return new String(e);
        } else {
            return null;
        }
    } else { //Outside Eclipse IDE
        return new String(c.readPassword("Password: "));
    }
}

此解决方法的缺点是,在Eclipse中,您将在程序运行时看到密码。

答案 3 :(得分:1)

类似于@Pshemo给出的答案,人们可​​以回到Swing:

final String passwd;
final String message = "Enter password";
if( System.console() == null ) { 
  final JPasswordField pf = new JPasswordField(); 
  passwd = JOptionPane.showConfirmDialog( null, pf, message, 
    JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) == JOptionPane.OK_OPTION 
      ? new String( pf.getPassword() ) : ""; 
} else 
  passwd = new String( System.console().readPassword( "%s> ", message ) );