I'm taking a cryptography course but some of the things my teacher describes are really not clear and badly explained.
He asked me to create an algorithm in Java to generate a RT table (hash/text) and to have a file (test.txt) that has 100 hashes to 'crack'. So I am at the stage where I have to compare the two files. But it seems to me too 'simple' I could look in my course and we talk about function reduction but I don't see how (when) to implement it.
I could already do the file reading and I could read line by line my big file and compare each hash with my small one. I don't know where and especially how to implement the function reduction in my algorithm and what it consists in.
Thank you very much for your help, if needed I put my code.
private static void bufferedReaderFilePasswordFirst() throws IOException {
Path path = Paths.get("C:\\Users\\basil\\OneDrive - Haute Ecole Bruxelles Brabant (HE2B)\\Documents\\NetBeansProjects\\sha256\\passwords.txt");
int nbOfLine = 0;
StringBuffer oui = new StringBuffer();
List<String> test = hashMap();
final DecimalFormat df = new DecimalFormat();
final DecimalFormatSymbols ds = df.getDecimalFormatSymbols();
ds.setGroupingSeparator('_');
df.setDecimalFormatSymbols(ds);
try (BufferedReader readerPasswordGenerate = Files.newBufferedReader(path, Charset.forName("UTF-8"));) {
String currentLinePassword = null;
long start = System.nanoTime();
while(((currentLinePassword = readerPasswordGenerate.readLine()) != null)){
String firstWord = currentLinePassword.substring(0, currentLinePassword.indexOf(":"));
int indexList = test.indexOf(firstWord);
if(indexList!=-1){
System.out.println(indexList);
String secondWord = currentLinePassword.substring(currentLinePassword.lastIndexOf(":") + 1);
oui.append(secondWord).append(System.lineSeparator());
}
nbOfLine++;
if(nbOfLine%1_000_000==0){
System.out.printf(
"%s / %s%n",
df.format(nbOfLine),
df.format(10000000));
}
}
System.out.println(oui);
final long consumed = System.nanoTime() - start;
final long totConsumed = TimeUnit.NANOSECONDS.toMillis(consumed);
final double tot = (double) totConsumed;
System.out.printf("Done. Took %s seconds", (tot / 1000));
} catch (IOException ex) {
ex.printStackTrace(); //handle an exception here
}
}
The test list is only a list of the 100 hash to crack
in my course and we talk about function reduction but I don't see how (when) to implement it.
I think you're confused about what rainbow tables even are, and how they differ from a simple table of passwords and the hashes of those passwords.
Rainbow tables are a way to save storage space in exchange for increasing the time needed to check each password hash against a candidate password compared to a full precomputed table of passwords and hashes.
Rainbow tables use a "reduction function". The reduction function takes in a hash and the column number (see below) and uses it to generate a possible password. Essentially it's a random password generator which uses a hash and column as its input seed.
Rainbow tables take a plaintext password candidate input, then repeatedly
hash the current plaintext
reduce the hash to a new plaintext
until some pre-chosen number of repetitions has finished, and hashes the final plaintext. Then you store only the starting password candidate and the final hash. Each iteration is a "column". Most aren't stored, but their numbers are used to vary the reduction function's outupt and prevent some problems.
To look up a password from its hash:
You now know which chain (if any) in the table this particular hash belongs to. Take that chain's starting plaintext, and start hashing & reducing it until you come to the known hash. The previous plaintext is the password!
Rainbow tables don't work against any password hashing system that uses "salt" values. The first such system was Unix's crypt
in 1976, so this tends to be a useless attack. It's still taught because the name is cool, and there are still people who make systems which don't salt their password hashes.
This article is a decent explanation. Wikipedia has more detail.