如何使用Scanner从Java中的STDIN静默读取?

Ric*_*ral 12 java stdin java.util.scanner

我想创建一个从STDIN静默读取密码的Java程序.我的意思是,不向终端输出任何按下的字符,并将其隐藏在命令行历史记录和操作系统进程列表中ps.

Eya*_*der 15

java.io.Console类可能很有用:

System.console().readPassword();
Run Code Online (Sandbox Code Playgroud)

这会从控制台读取一系列字符,而不会回显任何内容.请注意,它仅在您使用真实控制台启动Java应用程序时才有效.否则,System.console()返回null.


Eri*_*ski 5

通过 STDIN 获取密码的安全性较低的选项,适用于后台作业、虚拟控制台和普通控制台:

这更具兼容性,但安全性较低,它应该与 IDE 中的虚拟控制台一起使用,适用于没有 TTY 的后台进程和普通控制台。当找不到控制台时,它会回退到使用 BufferedReader,在某些情况下,当用户键入密码时,它将在屏幕上公开密码。

Java代码:

import java.io.*;
public class Runner {
    public static void main(String[] args) {
        String username = "Eric";

        try {
            ReadMyPassword r = new ReadMyPassword();
            char[] password = r.readPassword(
              "Hey %s, enter password to arm the nuclear wessels>", username);

            System.out.println("Exposing the password now: '" + 
                new String(password) + "'");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class ReadMyPassword{
    public char[] readPassword(String format, Object... args)
            throws IOException {
        if (System.console() != null)
            return System.console().readPassword(format, args);
        return this.readLine(format, args).toCharArray();
    }
    private String readLine(String format, Object... args) throws IOException {
        if (System.console() != null) {
            return System.console().readLine(format, args);
        }
        System.out.print(String.format(format, args));
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));
        return reader.readLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

通过 Eclipse 虚拟控制台看到的效果如下:

Hey Eric, enter password to arm the nuclear wessels>12345
Exposing the password now: '12345'
Program Sisko 197 ready for implementation on your command
Run Code Online (Sandbox Code Playgroud)

这是通过普通控制台看到的样子。

el@apollo:/home/el/bin$ java Runner
Hey Eric, enter password to arm the nuclear wessels>
Exposing the password now: 'abcdefg'
Program Sisko 197 ready for implementation on your command
el@apollo:/home/el/bin$
Run Code Online (Sandbox Code Playgroud)

  • 我相信第二个条件 (System.console() != null) 在这里只能为 false,不是吗?所以 System.console().readLine() 永远不会被调用...... (2认同)