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

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

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

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

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

  • 您不能使用System.in因为它可能没有连接到控制台。

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

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


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

也许不使用控制台尝试使用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)); 

我遇到了同样的问题。 (亲爱的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中,您将在程序运行时期间看到密码。

类似于@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 ) );