Как читать пароль с консоли без использования System.console()?
Я ударил эту ошибку затмения, где System.console()
недоступно для запуска приложений Java. У меня есть небольшое приложение Java, которое также требует ввода пароля, который запускается только из среды IDE. Есть ли другой способ безопасно читать пароль (то есть не отображать его на консоли) с консоли только с использованием классов JDK?
EDIT:
Я знаю System.in
, но это отображает введенные символы в консоли и поэтому не безопасно.
EDIT2:
Я также хочу отметить, что можно создать пакетный файл под окнами или небольшой bash script под linux/unix в проекте. Открыв этот файл в eclipse с помощью системного редактора по умолчанию, он будет запущен в новом окне консоли, где System.console()
доступен. Таким образом, вы можете запустить приложение из eclipse. но сначала нужно создать проект, чтобы существовали двоичные файлы.
Ответы
Ответ 1
Если System.console()
возвращает null
, это означает, что нет полезной консоли для Java.
-
Вы не можете использовать System.in
, потому что есть вероятность, что он не подключен к консоли.
-
Даже если бы вы могли, нет портативного способа отключить эхо в Java.
-
Возможно, вы сможете использовать Swing (или что-то еще), чтобы всплывать окно с запросом пароля, но если система безголовая, которая не будет работать.
Если вы готовы делать не переносные вещи, то (в Linux/UNIX) вы можете попробовать открыть "/dev/console" или "/dev/tty". И тогда вы можете использовать termios, чтобы включить драйвер tty в режим noecho. Но вам потребуется сделать хотя бы часть этого в собственном коде.
Ответ 2
Возможно, вместо консоли попробуйте использовать диалог с 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));
Ответ 3
Я столкнулся с той же проблемой. (Дорогое сообщество Eclipse: неужели так сложно исправить эту ошибку?)
Как и всем остальным, мне нужна среда IDE для dev/debug и автономная для работы.
Итак, я написал этот метод:
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 вы увидите пароль во время выполнения программы.
Ответ 4
Как и в ответе @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 ) );