Masking password input from the console : Java

118,430

Solution 1

A full example ?. Run this code : (NB: This example is best run in the console and not from within an IDE, since the System.console() method might return null in that case.)

import java.io.Console;
public class Main {

    public void passwordExample() {        
        Console console = System.console();
        if (console == null) {
            System.out.println("Couldn't get Console instance");
            System.exit(0);
        }

        console.printf("Testing password%n");
        char[] passwordArray = console.readPassword("Enter your secret password: ");
        console.printf("Password entered was: %s%n", new String(passwordArray));

    }

    public static void main(String[] args) {
        new Main().passwordExample();
    }
}

Solution 2

You would use the Console class

char[] password = console.readPassword("Enter password");  
Arrays.fill(password, ' ');

By executing readPassword echoing is disabled. Also after the password is validated it is best to overwrite any values in the array.

If you run this from an ide it will fail, please see this explanation for a thorough answer: Explained

Solution 3

Console console = System.console();
String username = console.readLine("Username: ");
char[] password = console.readPassword("Password: ");
Share:
118,430
New Start
Author by

New Start

Currently a Template Author/Developer at Electrum Ltd.

Updated on October 14, 2020

Comments

  • New Start
    New Start over 3 years

    How to mask a password from console input? I'm using Java 6.

    I've tried using console.readPassword(), but it wouldn't work. A full example might help me actually.

    Here's my code:

    import java.io.BufferedReader;
    import java.io.Console;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Test 
    {   
        public static void main(String[] args) 
        {   
            Console console = System.console();
    
            console.printf("Please enter your username: ");
            String username = console.readLine();
            console.printf(username + "\n");
    
            console.printf("Please enter your password: ");
            char[] passwordChars = console.readPassword();
            String passwordString = new String(passwordChars);
    
            console.printf(passwordString + "\n");
        }
    }
    

    I'm getting a NullPointerException...

  • New Start
    New Start over 12 years
    I just got another NullPointerException... I don't understand!
  • bilash.saha
    bilash.saha over 12 years
    Are you running this from within an IDE? Is not the code running ? Why downvote ?
  • New Start
    New Start over 12 years
    i didn't downvote, it must have been PTBG... I'm not sure why he did to be honest!
  • New Start
    New Start over 12 years
    yeah, it's not getting the Console instance... is that because i'm inside Eclipse?
  • bilash.saha
    bilash.saha over 12 years
    Its okey.This example is best run in the console and not from within an IDE, since the System.console() method might return null in that case.Run it in the console.It must work.Yes it may not work inside eclipse.
  • Sinisha Mihajlovski
    Sinisha Mihajlovski over 11 years
    For the guys getting the null pointer, run it from console, from eclipse this will not work
  • Woot4Moo
    Woot4Moo over 10 years
    need to fill the password array.
  • Woot4Moo
    Woot4Moo about 10 years
    This is also highly insecure.
  • ArtOfWarfare
    ArtOfWarfare about 9 years
    @Woot4Moo: Could you please elaborate how "the accepted answer is insecure!". I see you're writing over the password after you read it in, but this just seems silly. The password is going to be in memory for some amount of time no matter what you do. Even if you didn't manually write over the memory holding the password, it would get garbage collected and the memory would be refilled with something else. Honestly, if someone has the ability to read arbitrary addresses in memory, I think you should have bigger concerns.
  • Woot4Moo
    Woot4Moo about 9 years
    @ArtOfWarfare in the event the "answer" ever changes: stackoverflow.com/a/8138549/205426 the reason why it is insecure as I have stated is this: new String(passwordArray) a new String is allocated to the String Pool which "never" goes away during the lifetime of a JVM. To counter your statement about garbage collection, you may not be aware that the String class is "special" and doesn't get GCd. And yes I agree the password will be in memory for some amount of time, I just happen to reduce that amount of time as much as possible.
  • Woot4Moo
    Woot4Moo about 9 years
    @ArtOfWarfare additionally, any system as complex as the JVM is going to have issues with it. There have been a myriad of vulnerabilities discovered in the almost 4 years since I made this post, against the JVM. So if you were running the JVM since 2011 in Java 6 I bet there was a "arbitrary memory" exploit
  • M. Justin
    M. Justin over 8 years
    @Woot4Moo Can you clarify why this is "highly insecure"? Without any context of why, the statement alone isn't very useful for promoting understanding (nor is it easy to verify or refute).
  • inquisitive
    inquisitive over 8 years
    how to get password properly so that it will be running properly from console as well as the ide?
  • Pablo Torrecilla
    Pablo Torrecilla over 7 years
    For those who want to run their solutions both from console and the IDE, my solution is to have a switch statement. If the program runs without arguments enters the "interactive" mode with the console object, otherwise uses the given ones. Then, in your IDE you should be able to explicit a default set of arguments to run the application.
  • krevelen
    krevelen over 7 years
    Here's an example: 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 ) );
  • Abhigyan
    Abhigyan almost 7 years
    Hey, I exported the project as the runnable jar, and then run that jar from command line. but i'm still getting console null error. My other core java programs works well. This one is with selenium. Any advice for me ?
  • Igor Soudakevitch
    Igor Soudakevitch over 6 years
    @M.Justin Apparently, Woot4Moo in his 'highly insecure' comment was referring to the fact that the example not only failed to reset passwordArray to some garbage data but also created a String object instead of, say, iterating over the array with a for-each loop, etc. After all, this is exactly the reason why readPassword() returns a char[] rather than a String.
  • Patrick Parker
    Patrick Parker over 6 years
    There's not much sense in fretting over the internal memory security risk of a line that is literally printing the password out to the console.
  • Christopher Schultz
    Christopher Schultz about 5 years
    Overwriting the character values in the array is, at best, a band-aid. There is no guarantee that the contents of the "password" character array have not been copied around the heap a few times between the time that the password is read from the Console object and the time the Arrays.fill() method completes. The reality is that safe-handling of in-memory passwords in Java is simply not possible.