import java.io.Console; import java.util.Map; import java.util.HexFormat; import java.util.stream.Collectors; import java.nio.file.Path; import java.nio.file.Files; import java.security.MessageDigest; public class Auth { private static final byte[] INVALID_HASH = "----------------------------------------------------------------".getBytes(); public static void main(String[] args) { try { Map passwd = Files.readAllLines(Path.of("passwd")) .stream() .filter(line -> line.indexOf(":") > 1 && line.length() > 3) .collect(Collectors.toMap( line -> line.substring(0, line.indexOf(':')), line -> HexFormat.of().parseHex(line.substring(line.indexOf(':') + 1)) )); System.out.println("Chocolate Factory SCADA Command Line Interface v2.2.144"); System.out.println(); System.out.println("Please, enter your authentication credentials."); System.out.println(); Console cons = System.console(); String username; String password; long timeout = 500; while (true) { username = cons.readLine("> Username: "); password = new String(cons.readPassword("> Password: ")); MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] encodedHash = digest.digest(password.getBytes()); // constant time comparison to prevent timing attacks if (MessageDigest.isEqual( passwd.getOrDefault(username, INVALID_HASH), encodedHash )) { System.out.println(); System.out.printf("Welcome %s!%n", username); Thread.sleep(150); break; } else { // exponential timeout to prevent brute force attacks System.out.println("Incorrect username and/or password."); Thread.sleep(timeout); timeout *= 2; } } printSystemStatus(); printSecretRecipe(); } catch (Exception e) { // ignore } } private static void printSystemStatus() throws Exception { // TOP SECRET } private static void printSecretRecipe() throws Exception { // TOP SECRET } }