20

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

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

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

4

4 回答 4

5

也许代替控制台尝试使用带有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));
于 2013-03-01T14:40:00.690 回答
3

如果System.console()返回null,这意味着就 Java 而言没有可用的控制台。

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

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

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


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

于 2013-03-01T15:06:46.847 回答
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 中,您将在程序运行时看到密码。

于 2013-09-21T17:00:59.010 回答
2

与@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 ) );
于 2016-12-05T19:28:31.840 回答