0

I have program that randomly generates a password for a text file of usernames. I was wondering how I could check and make sure the user does not enter a invalid input and throw and error. I don't understand how to do a loop to check for valid inputs.

import java.util.Random;
import java.io.File;
import java.util.Scanner;
import java.io.PrintStream;
import java.lang.Math;

//Create class PasswordProgram
public class PasswordProgram {
    public static void main(String[] args) throws Exception {
        Random rand = new Random();

        // Read in the text file with usernames
        File infile = new File(args[0]);
        File outfile = new File("PasswordList.txt");

        Scanner kbd = new Scanner(System.in);
        Scanner Infile = new Scanner(infile);

        // Allowing All types of characters to be added
        PrintStream Outfile = new PrintStream(outfile);
        String uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String lowers = "abcdefghijklmnopqrstuvwxyz";
        String digits = "0123456789";
        String symbols = "`~!$%^&*()_+{}|:<>?/.,';][=-";
        String total = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                + "abcdefghijklmnopqrstuvwxyz"
                + "0123456789`~!$%^&*()_+{}|:<>?/.,';][=-";

        outfile.setReadable(true, true);

        // Ask user how many uppercase letters they want in their password
        System.out.print("Minumum uppercase: ");
        int Uppers = kbd.nextInt();

        // Ask user how many lowercase letters they want in their password
        System.out.print("Minumum lowercase: ");
        int Lowers = kbd.nextInt();

        // Ask user how many digits they want in their password
        System.out.print("Minumum digits: ");
        int Digits = kbd.nextInt();

        // Ask user how many symbols they want in their program
        System.out.print("Minumum symbols: ");
        int Symbols = kbd.nextInt();

        // Ask user how many total characters they want their password
        System.out.print("Minumum total characters: ");
        int Total = kbd.nextInt();
        char[] password = new char[Total];

        String user;
        int i, j, k;
        char temp;

        // As long as there is more usernames add more passwords
        while (Infile.hasNext()) {
            user = Infile.next();

            // Create random uppercase letters
            for (i = 0; i < Uppers; i++) {
                password[i] = uppers.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create random lowercase letters and add them to uppercase
            for (i = Uppers; i < (Uppers + Lowers); i++) {
                password[i] = lowers.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create random digits and add them to previous uppercase and
            // lowercase
            for (i = Uppers + Lowers; i < (Uppers + Lowers + Digits); i++) {
                password[i] = digits.charAt(Math.abs(rand.nextInt()) % 10);
            }

            // Create random symbols and add them to previous uppercase,
            // lowercase, and digits
            for (i = Uppers + Lowers + Digits; i < (Uppers + Lowers + Digits + Symbols); i++) {
                password[i] = symbols.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create total characters and make sure the password as at least
            // that length with uppercase, lowercase, digits, and symbols
            for (i = Uppers + Lowers + Digits + Symbols; i < Total; i++) {
                password[i] = total.charAt(Math.abs(rand.nextInt()) % 88);
            }

            // Print the generated passwords for each username
            System.out.println(user + " " + (new String(password)));
            Outfile.println(user + " " + (new String(password)));
        }
    }
}
Patrick M
  • 10,547
  • 9
  • 68
  • 101
Derk
  • 29
  • 1
  • 11
  • 4
    To begin with, [don't use java.util.Random for secure applications](http://stackoverflow.com/questions/11051205/difference-between-java-util-random-and-java-security-securerandom) – Alex Apr 02 '14 at 15:42
  • For one, you can use `SecureRandom` instead of just `Random` (pun intended). See, for example, [here](http://stackoverflow.com/questions/11051205/difference-between-java-util-random-and-java-security-securerandom) to learn the difference. – Gassa Apr 02 '14 at 15:43
  • why don't you define `total = upper + lowers + digits + symbols`? – CodesInChaos Apr 02 '14 at 15:44
  • 2
    Re: validation of inputs - you first need to define what you consider to be a valid or invalid input, before you can implement a validity check. – Alex Apr 02 '14 at 15:45
  • I want to make sure "uppers" are only uppercase letters and so on with the others. I define what I want them to be at String uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String lowers = "abcdefghijklmnopqrstuvwxyz"; String digits = "0123456789"; String symbols = "`~!$%^&*()_+{}|:<>?/.,';][=-"; String total = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789`~!$%^&*()_+{}|:<>?/.,';][=-"; – Derk Apr 02 '14 at 15:48
  • But you define those in code. How could they be invalid? The only input I'm seeing is reading a username from a file, which you don't do anything with other than write it to output. – Alex Apr 02 '14 at 15:52

2 Answers2

1
  1. Plaintext passwords are never a good thing. Hash them first.

  2. Why would you save all your usernames/passwords in a text file? Use a DBMS like MySQL. You can easily implement it in java using the MySQL JDBC Driver.

  3. If it is very necessary to use text files, loop through the username file and use a counter. Once you find the username, loop through the password file until you reach the specific line. Then, you can compare both passwords.

  4. If the password is wrong use,

    if(!input.equals(password)) { throw new Exception("Wrong password!"); }

individu
  • 359
  • 3
  • 4
0

Another suggestion:
What reason do you have all these questions to generate a user password ?
A random password is difficult to remember, asking about the number of special characters to be placed into it won't help a lot.

For generated passwords I would suggest to just make your own guideline and generate a password according to that instead of asking all those prompts.

But a modern password is often one-way hash encrypted, so you actually only store an encrypted form of the password and when a user enters the password again you encrypt it once again, then you match it with the encrpyted stored one.
This has the big benefit that the password can not be stolen and even if the encrypted hash is stolen it can not be 'decrypted' again.

You do not even need any special characters but I'd suggest to enforce a minimal length of 7-8 chars.
Here an example code on how to make an encrypted hash

MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update("CUSTOMSTRING"+pass.getBytes(), 0, 12+pass.length());
String md5 = new BigInteger(1, digest.digest()).toString(16);

This code will make a 16 byte MD5 hash out of any password and it adds a so called 'Salt" to it ("CUSTOMSTRING" in the example) which makes it very difficult to get the original password through brute force if someone steals the hash without access to the code.

I always hated websites that require you to have uppercase characters or special characters in the password as it makes me forget them. Passwords are not guessed these days, brute force can be detected too.

Summary:
Instead of generating the password based on user prompts, let the user choose one. Only require a minimal length which can be checked easily. And do not store the password, just store it's encrypted and salted hash.
In case of a security breach (database stolen) the attacker only has limited use for the password hashes.

John
  • 7,507
  • 3
  • 52
  • 52