2012-05-30 63 views
47

Sé que las interfaces de línea de comandos como Git y otros pueden ocultar la entrada de un usuario (útil para las contraseñas). ¿Hay alguna manera de hacerlo programáticamente en Java? Estoy tomando la entrada de contraseña de un usuario y me gustaría que su entrada esté "oculta" en esa línea en particular (pero no en todas). Aquí está mi código para ello (aunque dudo que sería útil ...)Ocultar entrada en la línea de comandos

try (Scanner input = new Scanner(System.in)) { 
    //I'm guessing it'd probably be some property you set on the scanner or System.in right here... 
    System.out.print("Please input the password for " + name + ": "); 
    password = input.nextLine(); 
} 

Respuesta

75

Trate java.io.Console.readPassword. Sin embargo, deberás ejecutar al menos Java 6.

/** 
    * Reads a password or passphrase from the console with echoing disabled 
    * 
    * @throws IOError 
    *   If an I/O error occurs. 
    * 
    * @return A character array containing the password or passphrase read 
    *   from the console, not including any line-termination characters, 
    *   or <tt>null</tt> if an end of stream has been reached. 
    */ 
    public char[] readPassword() { 
     return readPassword(""); 
    } 

Sin embargo, Aviso, este doesn't work con la consola de Eclipse. Tendrá que ejecutar el programa desde un verdadero console/shell/terminal/prompt para poder probarlo.

+21

+1 para avisarme que no funciona en la consola Eclipse (aunque utilizo Netbeans, aparentemente no funciona en ninguno de los dos). – kentcdodds

+1

ejercicio de ejemplo: http://www.tutorialspoint.com/java/io/console_readpassword.htm – mavis

+3

No funciona en la mayoría de los IDE ya que usan javaw. Ver http://stackoverflow.com/a/26473083/3696510 – muttonUp

3

No:

Console cons; 
char[] passwd; 
if ((cons = System.console()) != null && 
    (passwd = cons.readPassword("[%s]", "Password:")) != null) { 
    ... 
    java.util.Arrays.fill(passwd, ' '); 
} 

source

pero no creo que esto funciona con un IDE como Eclipse porque el programa se ejecuta como un proceso en segundo plano en lugar de un proceso de nivel superior con una consola ventana.

Otro enfoque es utilizar el JPasswordField en el swing con el método de acompañamiento actionPerformed:

public void actionPerformed(ActionEvent e) { 
    ... 
    char [] p = pwdField.getPassword(); 
} 

source

11

Sí se puede hacer. Esto se llama enmascaramiento de entrada de línea de comando. Puedes implementar esto fácilmente.

Puede utilizar una secuencia separada para borrar los caracteres repetidos a medida que se ingresan, y los reemplaza con asteriscos. Esto se hace utilizando la clase EraserThread se muestra a continuación

import java.io.*; 

class EraserThread implements Runnable { 
    private boolean stop; 

    /** 
    *@param The prompt displayed to the user 
    */ 
    public EraserThread(String prompt) { 
     System.out.print(prompt); 
    } 

    /** 
    * Begin masking...display asterisks (*) 
    */ 
    public void run() { 
     stop = true; 
     while (stop) { 
     System.out.print("\010*"); 
    try { 
     Thread.currentThread().sleep(1); 
     } catch(InterruptedException ie) { 
      ie.printStackTrace(); 
     } 
     } 
    } 

    /** 
    * Instruct the thread to stop masking 
    */ 
    public void stopMasking() { 
     this.stop = false; 
    } 
} 

Con el uso de este hilo

public class PasswordField { 

    /** 
    *@param prompt The prompt to display to the user 
    *@return The password as entered by the user 
    */ 
    public static String readPassword (String prompt) { 
     EraserThread et = new EraserThread(prompt); 
     Thread mask = new Thread(et); 
     mask.start(); 

     BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
     String password = ""; 

     try { 
     password = in.readLine(); 
     } catch (IOException ioe) { 
     ioe.printStackTrace(); 
     } 
     // stop masking 
     et.stopMasking(); 
     // return the password entered by the user 
     return password; 
    } 
} 

This Link discutir en detalles.

+1

http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain -links-elsewhere-really-good-answers –

+0

Estoy buscando esta respuesta y me gusta el enmascaramiento de contraseñas. Pero incluya el contenido del artículo que considere útil para que esta sea una buena respuesta. – kentcdodds

+1

+1 para publicar el código relevante. – kentcdodds

7

JLine 2 pueden ser de su interés. Además del enmascaramiento de caracteres, proporcionará funciones de finalización, edición e historial de línea de comandos. En consecuencia, es muy útil para una herramienta Java basada en CLI.

para enmascarar su entrada:

String password = new jline.ConsoleReader().readLine(new Character('*')); 
0

Console La clase tiene un método readPassword() que podría resolver su problema.

-2

Si usted está tratando con una matriz de caracteres de Java (como caracteres de la contraseña que se lee desde la consola), se puede convertir en una cadena JRuby con el siguiente código Ruby:

# GIST: "pw_from_console.rb" under "https://gist.github.com/drhuffman12" 

jconsole = Java::java.lang.System.console() 
password = jconsole.readPassword() 
ruby_string = '' 
password.to_a.each {|c| ruby_string << c.chr} 

# .. do something with 'password' variable ..  
puts "password_chars: #{password_chars.inspect}" 
puts "password_string: #{password_string}" 

Véase también "https://stackoverflow.com/a/27628738/4390019" y "https://stackoverflow.com/a/27628756/4390019"

Cuestiones relacionadas