+1 (315) 557-6473 

Create A Login System in Java Assignment Solution.


Instructions

Objective
Write a program to create a login system in java.

Requirements and Specifications

Description: A login system that enforces the following rules: At least 8 characters; A mixture of both uppercase and lowercase letters; Inclusion of at least one number and one special character, e.g.,! @ # ? ]; Mask or hide the passwords while the user is typing; Limit the number of attempts that a user can make. The passwords must be stored using an appropriate cryptographic solution. Java programming only, a robust system, only interaction with the console.
Screenshot
Program to create a login system in java language

Source Code

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.PBEKeySpec;

import java.io.Console;

import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.security.NoSuchAlgorithmException;

import java.security.spec.InvalidKeySpecException;

import java.util.*;

import java.util.function.Predicate;

public class LoginSystem {

 private static final int DEFAULT_LOGIN_ATTEMPTS = 3;

 private static final String LOGIN_DATA_FILENAME = "data.txt";

 private final Map data;

 private final Collection rules;

 private int loginAttemptsLeft;

 private String salt;

 public LoginSystem(Collection rules, int loginAttempts) {

  this.rules = rules;

  loginAttemptsLeft = loginAttempts;

  data = new HashMap<>();

  try (Scanner scanner = new Scanner(new File(LOGIN_DATA_FILENAME))) {

   salt = scanner.nextLine().trim();

   while (scanner.hasNextLine()) {

    String[] parts = scanner.nextLine().trim().split("\\s+");

    if (parts.length != 2) {

     continue;

    }

    data.put(parts[0], parts[1]);

   }

  } catch (IOException e) {

   System.out.println("Can not open data file.");

   salt = EncryptionUtils.generateSalt();

  }

 }

 public LoginSystem(Collection rules) {

  this(rules, DEFAULT_LOGIN_ATTEMPTS);

 }

 public LoginSystem(int loginAttempts) {

  this(Collections.emptyList(), loginAttempts);

 }

 public LoginSystem() {

  this(Collections.emptyList(), DEFAULT_LOGIN_ATTEMPTS);

 }

 public boolean isBlocked() {

  return loginAttemptsLeft == 0;

 }

 public boolean tryLogin(String login, String password) {

  if (isBlocked()) {

   return false;

  }

  boolean isOK = true;

  String loginEnc = EncryptionUtils.getHashed(login, salt);

  if (!data.containsKey(loginEnc)) {

   isOK = false;

  } else {

   String passwordEnc = EncryptionUtils.getHashed(password, salt);

   isOK = passwordEnc.equals(data.get(loginEnc));

  }

  if (!isOK) {

   loginAttemptsLeft--;

  }

  return isOK;

 }

 public boolean signUp(String login, String password, String repeatPassword) {

  if (!checkPassword(password)) {

   System.out.println("Password does not satisfy security requiements");

   return false;

  }

  if (!password.equals(repeatPassword)) {

   System.out.println("Passwords do not match");

   return false;

  }

  String loginEnc = EncryptionUtils.getHashed(login, salt);

  if (data.containsKey(loginEnc)) {

   System.out.println("User with such login already exists");

   return false;

  }

  String passwordEnc = EncryptionUtils.getHashed(password, salt);

  data.put(loginEnc, passwordEnc);

  save();

  return true;

 }

 private void save() {

  try (PrintWriter printWriter = new PrintWriter(LOGIN_DATA_FILENAME)) {

   printWriter.println(salt);

   for (Map.Entry entry : data.entrySet()) {

    printWriter.println(entry.getKey() + " " + entry.getValue());

   }

  } catch (IOException e) {

   System.out.println("Can not open data file for writing");

  }

 }

 public boolean checkPassword(String password) {

  return rules.stream().allMatch(r -> r.check(password));

 }

 private static class EncryptionUtils {

  private static final int SALT_LENGTH = 32;

  private static final int KEY_LENGTH = 256;

  private static final String SALT_SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

  public static String generateSalt() {

   StringBuilder builder = new StringBuilder();

   Random random = new Random();

   for (int i = 0; i < SALT_LENGTH; i++) {

    builder.append(SALT_SYMBOLS.charAt(random.nextInt(SALT_SYMBOLS.length())));

   }

   return builder.toString();

  }

  public static String getHashed(String s, String salt) {

   char[] cArray = s.toCharArray();

   PBEKeySpec spec = new PBEKeySpec(cArray, salt.getBytes(), 1000, KEY_LENGTH);

   Arrays.fill(cArray, Character.MIN_VALUE);

   try {

    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

    return Base64.getEncoder().encodeToString(skf.generateSecret(spec).getEncoded());

   } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {

    throw new IllegalArgumentException("Error while hashing a string: " + e.getMessage(), e);

   } finally {

    spec.clearPassword();

   }

  }

 }

 private interface PasswordRule {

  boolean check(String password);

 }

 private static class LengthRule implements PasswordRule {

  private final int minLength;

  public LengthRule(int minLength) {

   this.minLength = minLength;

  }

  @Override

  public boolean check(String password) {

   return password.length() >= minLength;

  }

 }

 private static class CharactersNeededRule implements PasswordRule {

  private final Predicate test;

  public CharactersNeededRule(Predicate test) {

   this.test = test;

  }

  public CharactersNeededRule(Collection chars) {

   this(chars::contains);

  }

  @Override

  public boolean check(String password) {

   return password.chars().mapToObj(c -> (char) c).anyMatch(test);

  }

 }

 public static class UpperCaseNeededRule extends CharactersNeededRule {

  public UpperCaseNeededRule() {

   super(c -> Character.isAlphabetic(c) && Character.isUpperCase(c));

  }

 }

 public static class LowerCaseNeededRule extends CharactersNeededRule {

  public LowerCaseNeededRule() {

   super(c -> Character.isAlphabetic(c) && Character.isLowerCase(c));

  }

 }

 public static class SpecialCharactersNeededRule extends CharactersNeededRule {

  public SpecialCharactersNeededRule() {

   super(Arrays.asList('!', '@', '#', '?'));

  }

 }

 public static void main(String[] args) {

  List rules = new ArrayList<>();

  rules.add(new LengthRule(8));

  rules.add(new UpperCaseNeededRule());

  rules.add(new LowerCaseNeededRule());

  rules.add(new SpecialCharactersNeededRule());

  LoginSystem loginSystem = new LoginSystem(rules, 5);

  Console scanner = System.console();

  System.out.print("Do you want to sign up new user? (y/n): ");

  boolean signUpNeeded = scanner.readLine().trim().equalsIgnoreCase("y");

  while (signUpNeeded) {

   System.out.print("Enter login: ");

   String login = scanner.readLine();

   System.out.print("Enter password: ");

   String password = new String(scanner.readPassword());

   System.out.print("Enter repeat password: ");

   String repeatPassword = new String(scanner.readPassword());

   if (loginSystem.signUp(login, password, repeatPassword)) {

    System.out.println("User created successfully");

   }

   System.out.print("Do you want to sign up new user? (y/n): ");

   signUpNeeded = scanner.readLine().trim().equalsIgnoreCase("y");

  }

  System.out.println("Trying to log in:");

  boolean success = false;

  while (!loginSystem.isBlocked() && !success) {

   System.out.print("Login: ");

   String login = scanner.readLine().trim();

   System.out.print("Password: ");

   String password = new String(scanner.readPassword());

   if (loginSystem.tryLogin(login, password)) {

    success = true;

   } else {

    System.out.println("Wrong login/password");

   }

   System.out.println();

  }

  if (success) {

   System.out.println("You were successfully logged in");

  } else {

   System.out.println("You have no more attempts to log in. FAIL");

  }

 }

}