From c63e69fc93ca56de241a79225c83db35d18e4481 Mon Sep 17 00:00:00 2001 From: Nathan Woodburn Date: Mon, 23 Oct 2023 18:50:45 +1100 Subject: [PATCH] feat: Add peppered hash --- README.md | 1 + guesser.java | 118 ++++++++++++++++++++++++++++++++++++++++++++++ pepperedHash.java | 63 +++++++++++++++++++++++++ saltedHash.java | 6 +-- 4 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 guesser.java create mode 100644 pepperedHash.java diff --git a/README.md b/README.md index a5461ce..27bdbbb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ 1. [Hashing](hash.java) 2. [Salted Hashing](saltedHash.java) +3. [Peppered Hashing](pepperedHash.java) diff --git a/guesser.java b/guesser.java new file mode 100644 index 0000000..eed0862 --- /dev/null +++ b/guesser.java @@ -0,0 +1,118 @@ +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +public class guesser { + public static void main(String[] args) throws NoSuchAlgorithmException { + System.out.println("Guessing hash of a random 6 digit password"); + Random random = new Random(); + int seed= random.nextInt(1000000); + String randomPassword = getRandomPassword(seed); + System.out.println("Random 6-character string: " + randomPassword); + + System.out.println("Hashed password"); + String hashed = hash.hashstring(randomPassword); + System.out.println(hashed); + + System.out.println("Guessing..."); + long startTime = System.nanoTime(); + + + boolean match = false; + int check=0; + while (!match) { + String guess = getRandomPassword(check); + check++; + String hashedGuess = hash.hashstring(guess); + if (hashedGuess.equals(hashed)) { + match = true; + System.out.println("Match!"); + System.out.println("Password is: " + guess); + } + } + + long endTime = System.nanoTime(); + long duration = (endTime - startTime); + // Calculate the time taken in seconds + double seconds = (double)duration / 1_000_000_000.0; + System.out.println("Time taken: " + seconds + " seconds"); + + System.out.println("Guessing hash of a random 6 digit password with salt"); + System.out.println("Hashed password"); + String salt = bytetohex.toHexString(saltedHash.getSalt()); + // Remove starting 0s + while (salt.charAt(0) == '0') { + salt = salt.substring(1); + } + String salted = randomPassword + salt; + String hashedSalted = hash.hashstring(salted); + + System.out.println("Guessing..."); + startTime = System.nanoTime(); + + match = false; + check=0; + while (!match) { + String guess = getRandomPassword(check); + check++; + String saltedGuess = guess + salt; + String hashedGuess = hash.hashstring(saltedGuess); + if (hashedGuess.equals(hashedSalted)) { + match = true; + System.out.println("Match!"); + System.out.println("Password is: " + guess); + } + } + + endTime = System.nanoTime(); + duration = (endTime - startTime); + seconds = (double)duration / 1_000_000_000.0; + System.out.println("Time taken: " + seconds + " seconds"); + + + System.out.println("Guessing hash of a random 6 digit password with pepper"); + + System.out.println("Hashed password"); + String pepper = pepperedHash.getPepper(); + String peppered = randomPassword + pepper; + String hashedPeppered = hash.hashstring(peppered); + + System.out.println("Guessing..."); + startTime = System.nanoTime(); + match = false; + check=0; + + while (!match) { + String guess = getRandomPassword(check); + check++; + if (pepperedHash.checkPeppered(guess,hashedPeppered)) { + match = true; + System.out.println("Match!"); + System.out.println("Password is: " + guess); + } + } + endTime = System.nanoTime(); + duration = (endTime - startTime); + seconds = (double)duration / 1_000_000_000.0; + System.out.println("Time taken: " + seconds + " seconds"); + + + + } + + private static String getRandomPassword(int value) { + // Define the characters that can be used in the random string + String characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + // Initialize a StringBuilder to build the random string + StringBuilder randomString = new StringBuilder(6); + + // Generate a string using the value + for (int i = 0; i < 6; i++) { + randomString.append(characters.charAt(value % characters.length())); + value /= characters.length(); + } + + + return randomString.toString(); + } +} diff --git a/pepperedHash.java b/pepperedHash.java new file mode 100644 index 0000000..caa4d2b --- /dev/null +++ b/pepperedHash.java @@ -0,0 +1,63 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.NoSuchAlgorithmException; +import java.util.Random; + +public class pepperedHash { + public final static String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public static void main(String[] args) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("Enter a string to hash and salt: "); + String input = reader.readLine(); + + try { + String pepper = getPepper(); + System.out.println("Pepper is: " + pepper); + // Remove starting 0s + + String peppered = input + getPepper(); + System.out.println("Hashed as:"); + String hashed = hash.hashstring(peppered); + System.out.println(hashed); + + System.out.println("Enter a string to check: "); + String check = reader.readLine(); + + if (checkPeppered(check,hashed)){ + System.out.println("Match!"); + } else { + System.out.println("No match!"); + } + + + + } catch (NoSuchAlgorithmException e) { + System.out.println(e.toString()); + } + } + + public static boolean checkPeppered(String check,String hashed) throws NoSuchAlgorithmException { + boolean match = false; + for (int i = 0; i<52;i++){ + String pepperedCheck = check + alphabet.charAt(i); + String hashedCheck = hash.hashstring(pepperedCheck); + if (hashedCheck.equals(hashed)) { + match = true; + break; + } + } + return match; + } + + public static String getPepper() { + // Return random a-zA-Z + Random random = new Random(); + int randomIndex = random.nextInt(52); + + // Get the random character + char randomChar = alphabet.charAt(randomIndex); + return Character.toString(randomChar); + } +} \ No newline at end of file diff --git a/saltedHash.java b/saltedHash.java index 6734b2b..711cd76 100644 --- a/saltedHash.java +++ b/saltedHash.java @@ -20,14 +20,14 @@ public class saltedHash { String salted = input + salt; System.out.println("Hashed as:"); String hashed = hash.hashstring(salted); - String stored = hashed + ":"+salt; + String stored = hashed + "$"+salt; System.out.println(stored); System.out.println("Enter a string to check: "); String check = reader.readLine(); // Split stored by the colon - String[] parts = stored.split(":"); + String[] parts = stored.split("\\$"); // Salt the checked String saltedCheck = check + parts[1]; // Hash the salted checked @@ -46,7 +46,7 @@ public class saltedHash { } - private static byte[] getSalt() throws NoSuchAlgorithmException { + public static byte[] getSalt() throws NoSuchAlgorithmException { SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; random.nextBytes(salt);