Password Masking in Java with Scanner - java

I'm a high school student learning Java and I want to know how to change input text automatically into an asterisk in Scanner. This is for a simple log-in system I have made for a project. My code is
Scanner scan = new Scanner(System.in);
boolean correctLogin = false;
String username;
String password;
String enteredUsername;
String enteredPassword;
while(correctLogin != true){
System.out.println("Enter Username: ");
enteredUsername = scan.nextLine();
System.out.println("Enter Password: ");
enteredPassword = scan.nextLine();
if(enteredUsername.equals("username") && enteredPassword.equals("passw00rd")){
System.out.println("You have entered the correct login info");
correctLogin = true;
break;
}
else{
System.out.println("Your login info was incorrect, please try again");
}
}
System.out.println("You are now logged in, good job!");
I want it so that when I type the password, it will automatically change into an asterisk.

try with this for password read:
Console console = System.console();
if(console != null){
console.readPassword("Enter Password: ");
}

I also had the same issue with my console java application and
I also do not want to display password in my IDE for security reasons.
So, to find the bug I had to debug against the productive environment. Here is my solution that works for me in IntelliJ IDEA:
public static String getPassword() {
String password;
Console console = System.console();
if (console == null) {
password = getPasswordWithoutConsole("Enter password: ");
} else {
password = String.valueOf(console.readPassword("Enter password: "));
}
return password;
}
public static String getPasswordWithoutConsole(String prompt) {
final JPasswordField passwordField = new JPasswordField();
return JOptionPane.showConfirmDialog(
null,
passwordField,
prompt,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION ? new String(passwordField.getPassword()) : "";
}

I am not sure if i get your question correctly, but still I will try to explain of what I understood.
To ensure that you see *** on the user screen you need to have some kind of a User interface written in HTML. I think in this case you are running your code in eclipse and via some kind of a main method. If that is the case then as Vince mentioned there is no benefit of ** since the letters would appear in the console.
What I would recommend is look for something basic web application tutorial and you would have more idea on how it works then.
HTH

Related

Java help JOptionPane Madness

Really needing help on this have been trying for the past hour playing around and can't seem to get it. Have looked for the question online and getting a lot of solutions that are similar but not quite accomplishing the task would appreciate if someone could help me with this?
I am currently working on a dropBox API and am trying to create a JOptionPane that prompts the user to enter the code generated from dropBox API and the program to read the input and verify.. I have done the System.in with success but this is for a GUI so obviously not helpful.
System.out.println("Enter Your auth code in this prompt and hit enter and wait..");
String result = JOptionPane.showInputDialog(null, "Enter Code Here: ");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine();
// Want JOptionPane to function the same way this ^ would behave
String info = JOptionPane.showInputDialog(code +" test " );
if(code == null){
System.exit(1);
return;
}
code = code.trim();
// This will fail if the user enters an invalid authorization code.
DbxAuthFinish authFinish = webAuth.finish(code);
String accessToken = authFinish.accessToken;
DbxClient client = new DbxClient(config, accessToken);
System.out.println("Linked account: " + client.getAccountInfo().displayName);
JOptionPane.showMessageDialog(null, "Hello..."+
client.getAccountInfo().displayName+
" And Welcome To Our Community!");
The String 'result' should hold the code they entered into the JOptionPane.
EDIT #1:
String result = JOptionPane.showInputDialog(null, "Enter your auth code here:"); //Prompt for the auth code.
//If they didn't enter anything into the JOptionPane then close the program with code 1.
if (result.isEmpty()) {
System.exit(1);
}
System.out.println(result.trim()); //For testing purposes print the trimmed auth code to console.
// [Omitted Code] //
Also, you don't need to call return after a System.exit(#) because the program will never get to that code anyway.

Java: How to Automatically Restart A Console Program If The "Else" Statement Is Triggered

I am making a simple program that asks for a password before you can start the program. When my user inputs the wrong password, they get an "Access Denied," warning. I achieve this using an If/Else Statement. What I want to be able to do is to re-run my program if they enter the wrong password, as they cannot type in the console again if they get it wrong.
Here is my workspace:
import java.util.Scanner;
public class PasswordProtected {
public static void main (String args[]){
Scanner Password = new Scanner (System.in);
String mainpassword, userInput;
mainpassword = ("Jacob");
System.out.println("Please enter the password to continue.");
userInput = Password.nextLine();
System.out.println("Verifying Password");
if (userInput.equals(mainpassword)){
System.out.println("Access Granted");
System.out.println("Welcome!");
}else{
System.out.println("Access Denied");
}
}
}
I do realize that I could copy some thing like this over and over again, however, it is a waste of space is is not unlimited.
System.out.println("Please enter the password to continue.");
userInput = Password.nextLine();
System.out.println("Verifying Password");
if (userInput.equals(mainpassword)){
System.out.println("Access Granted");
System.out.println("Welcome!");
}else{
System.out.println("Access Denied");
}
}
Please note that I am new at programming, and may need a bit of extra help.
If the Else Statement is triggered, how can I fully restart my program without the use of manually clicking the run button again?
You don't need to restart your program. Use a loop to ask for the password again if it is incorrect. For example in semi-pseudo code with while statement:
userInput = input.nextLine();
while ( !userInput.equals(mainpassword) ){
userInput = input.nextLine();
}
Try while(true) loop
String mainpassword = ("Jacob");
String userInput = null;
Scanner Password = new Scanner (System.in);
while(true) {
userInput = Password.nextLine();
if (userInput.equals(mainpassword)){
break;
} else {
System.out.println("Access Denied");
}
}
System.out.println("Access Granted");
System.out.println("Welcome!");
If you still feel to restart any Java program, then the main() method can be called from anywhere else in your code. You can just call this method, passing in any necessary String parameters. Use a thread to do so, as below
Thread t = new Thread() {
public void run() {
String[] args = { };
PasswordProtected.main(args);
}
};
t.start();
If you want to re-launch your application in a new process, you can use
Runtime.getRuntime().exec(...);

Hide Password From Console Window Java Asterisk Password Or Block Inputted String Being Displayed

public class Login {
protected static String user, pass, host;
Object conn;
public void Login() throws SQLException
{
try {
Class.forName ("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println ("Could not load the driver");
}
Scanner sc = new Scanner(System.in);
Console console = System.console();
System.out.println("Please Enter Username");
user = sc.next();
System.out.println("Please Enter Password");
pass = sc.nextLine();
System.out.println("Please Enter Host/IP Address");
host = sc.next();
System.out.println("Attempting Log In");
Connection conn = (Connection) DriverManager.getConnection
("jdbc:mysql://"+host+":3306/chessdb", user, pass);
Just bit of help, been looking around online at blocking the password being shown on the console window. Is there a simple method of either the inputted text not appearing at all or else an asterisk to cover the input of the password field only?
Use the readPassword() method.
instead of using scanner like
System.out.println("Please Enter Password");
pass = sc.nextLine();
use:
System.out.println("Please Enter Password");
char[] passString = Console.readPassword();
String pass = new String(passString );
Use java.io.Console.readPassword() method
See API in below link
https://docs.oracle.com/javase/7/docs/api/java/io/Console.html
java.io.Console has a method for reading passwords with output disabled: Console#readPassword.

Java does not append to the .DAT file

I am writing a basic program that has 3 menu options: Create User, Sign In, and Exit. The user can then choose one of these menu options.
If they choose Create User, they will be prompted to enter a User ID and password (which must follow patterns), and will then check against a .DAT file to ensure the User ID has not already been taken. After successful completion, the program will write the new User ID and password to the end of the .DAT file.
If they choose Sign In, they will be prompted to enter their User ID, followed by their Password, and the program will then read the .DAT file to validate they are on record.
Choosing exit will display a message, "You have signed out."
I am fairly new at java programming just as a forewarning.
Issues I am encountering with my code:
Choosing new user does not append to the .DAT file
Choosing Sign In - program does not seem to correctly check .DAT file because even-
though I am entering an existing account information it still gives my error "Invalid User ID."
import java.io.*;
import java.util.*;
/**
* This program will utilize a menu structure and validate input if the user doesn't choose
* a correct option. Writes a new ID and password to .dat file when user chooses to
* create new user from menu.
*
* #author CMS
* #Date 7/28/2014
*/
public class Passwordv2 {
static boolean answer = true;
static final String MENUANSW = "[1-3]{1}", USERID = "[A-Z,a-z]{6}-[0-9]{2}"; //, PASSWORD = "";
static String iMenuOption="", iID, recPassword, recUserID, password;
static Scanner scanner,scannerDat;
static PrintWriter pw;
public static void main(String[] args) {
init();
while (answer == true) {
menu();
if (iMenuOption.equals("1")) createUser();
else
if (iMenuOption.equals("2")) signIn();
else {answer = false;}
}
closing();
} // end of main
public static void init(){
//User input scanner
scanner = new Scanner(System.in);
//PrintWriter
try {
pw = new PrintWriter(new FileOutputStream (new File ("account.dat"),true) );
}
catch(FileNotFoundException ex) {
}
} // end of INIT
public static String menu(){
do {System.out.println("Please select from the following:");
System.out.println("1. Create a New User");
System.out.println("2. Sign in");
System.out.println("3. Exit");
iMenuOption = scanner.next();
answer = isValMenuOption(iMenuOption);
if (answer == false) { System.out.print("Incorrect Choice. ");}
} while (!answer);
return iMenuOption;
}
public static boolean isValMenuOption(String iMenuOption) {
return(iMenuOption.matches(MENUANSW));
}
public static void createUser() {
boolean validID = true, newID = true;
do {if (!validID) {System.out.println("User ID did not meet requirements.");}
if (!newID) {System.out.println("This User ID has been taken.");}
System.out.println("Please select a User Id (6 letters, followed by a dash (-), followed by 2 numbers).");
iID = scanner.next();
validID = isValidID(iID);
newID = isNewID(iID);}
while (validID==false || newID == false);
boolean valLength = true, valNum = true, valUpper = true, valLower = true;
do{ System.out.println("Please select a Password:");
System.out.println("(6-12 characters, one number, one upper case, one lower case, no white space or symbols).");
password = scanner.next();
valLength = isValLength(password);
valNum = valNum(password);
valUpper = valUpper(password);
valLower = valLower(password);}
while (!valLength || !valNum || !valUpper || !valLower);
pw.println(iID);
pw.println(password);
//menu();
}
public static boolean isValidID(String iID){
return(iID.matches(USERID));
}
public static boolean isNewID(String iID){
answer = true;
// Dat file scanner
try {
scannerDat = new Scanner(new File("account.dat"));
scannerDat.useDelimiter("\r\n");
}
catch (Exception e) {
e.printStackTrace();
System.out.println("File error");
System.exit(1);
}
while (scannerDat.hasNext()) {
recUserID = scannerDat.next();
recPassword = scannerDat.next();
if (recUserID.equals(iID)) {
answer = false;
break;
}
}
return answer;
}
public static boolean isValLength(String password) {
if (password.length() <6 || password.length() > 12) System.out.println("Password did not meet length requirements. ");
return(password.length() >= 6 && password.length() <= 12);
}
public static boolean valNum(String password) {
if (password.matches(".*[0-9].*") == false) System.out.println("Password must contain at least one number. ");
return(password.matches(".*[0-9].*"));
}
public static boolean valUpper(String password){
if (password.matches(".*[A-Z].*") == false) System.out.println("Password must contain one upper case letter.");
return (password.matches(".*[A-Z].*"));
}
public static boolean valLower(String password){
if (password.matches(".*[a-z].*") == false) System.out.println("Password must contain one lower case letter.");
return (password.matches(".*[a-z].*"));
}
public static void signIn() {
boolean newID;
System.out.println("Enter User ID.");
iID = scanner.next();
System.out.println("Enter Password.");
password = scanner.next();
newID = isNewID(iID);
if (newID == false) {
if (password.equals(recPassword)) {System.out.println("Authenticated. You have signed in.");}
else {System.out.println("Invalid Password.");}
}
else {System.out.println("Invalid User ID.");}
}
public static void closing(){
System.out.println("You signed out.");
pw.close();
}
} // end of program
My .DAT file simply has
aabbcc-11
Onetwo3
aaabbb-22
Onetwo34
Change this line:
scannerDat.useDelimiter("\r\n");
to
scannerDat.useDelimiter("\n");
Works for me!
The first bad thing you are doing is that you have a PrintWriter (pw) and a Scanner (scannerDat) both accessing the same file and neither of them closing the access to the file, except right at the end, the pw is closed.
isNewId is the main culprit. Inside here you are better off using a FileReader instead of a Scanner. Declare the FileReader locally within the method and ensure that the file access is closed before exiting, this procedure.
Also within isNewId - don't call System.exit(); In a program this size it's OK, but anything bigger than this it is a cardinal sin and you should never just exit a program as ungracefully as this.
You need to flush your PrintWriter in order for it to do append to the file immediately. Otherwise it would just store it in the buffer to write it into the file eventually
Also, please check what user #simo.3792095 said about your code. You should not have several file streams opened at the same time. Either open/close your streams every time you do something with them, or read the whole data file on program start, then work with in-memory data, then save on exit. It is much easier to work with in-memory data, but if your program crashes all of the in-memory changes will be lost.
Thanks for all who replied. In the end, the problem ended up being that I had a "rough draft" java class, which I then copied and pasted the code of into a new java class under the same java project, which seemed to be giving me issues. Once I created a new java project and used the valid java class it worked fine. I also added the pw.flush(); method to my code so I was able to append to the file immediately instead of upon closing. Also removed the system.exit.

Hide input on command line

I know that command line interfaces like Git and others are able to hide input from a user (useful for passwords). Is there a way to programmtically do this in Java? I'm taking password input from a user and I would like their input to be "hidden" on that particular line (but not on all of them). Here's my code for it (though I doubt it would be helpful...)
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();
}
Try java.io.Console.readPassword. You'll have to be running at least Java 6 though.
/**
* 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("");
}
Beware though, this doesn't work with the Eclipse console. You'll have to run the program from a true console/shell/terminal/prompt to be able to test it.
Yes can be done. This is called Command-Line Input Masking. You can implement this easily.
You can uses a separate thread to erase the echoed characters as they are being entered, and replaces them with asterisks. This is done using the EraserThread class shown below
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;
}
}
With using this thread
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 discuss in details.
JLine 2 may be of interest. As well as character masking, it'll provide command-line completion, editing and history facilities. Consequently it's very useful for a CLI-based Java tool.
To mask your input:
String password = new jline.ConsoleReader().readLine(new Character('*'));
There is :
Console cons;
char[] passwd;
if ((cons = System.console()) != null &&
(passwd = cons.readPassword("[%s]", "Password:")) != null) {
...
java.util.Arrays.fill(passwd, ' ');
}
source
but I don't think this works with an IDE like Eclipse because the program is run as a background process rather than a top level process with a console window.
Another approach is to use the JPasswordField in swing with the accompanying actionPerformed method:
public void actionPerformed(ActionEvent e) {
...
char [] p = pwdField.getPassword();
}
source
Here is an example using console.readPassword(...); in an IDE. I use Netbeans. Note: In your IDE, Scanner will be used and it will show the password!. In the console, console.readPassword(..) will be used and it will not show the password!.
public static void main(String[] args) {
//The jar needs to be run from the terminal for console to work.
Scanner input = new Scanner(System.in);
Console console = System.console();
String username = "";
String password = "";
if (console == null)
{
System.out.print("Enter username: ");
username = input.nextLine();
System.out.print("Enter password: ");
password = input.nextLine();
}
else
{
username = console.readLine("Enter username: ");
password = new String(console.readPassword("Enter password: "));
}
//I use the scanner for all other input in the code!
//I do not know if there are any pitfalls associated with using the Scanner and console in this manner!
}
Note: I do not know if there are any pitfalls associated with using the Scanner and console in this manner!
The class Console has a method readPassword() that might solve your problem.

Categories

Resources