282 lines
11 KiB
TeX
282 lines
11 KiB
TeX
\documentclass[a4paper]{article}
|
|
\input{head}
|
|
\begin{document}
|
|
|
|
%-------------------------------
|
|
% TITLE SECTION
|
|
%-------------------------------
|
|
|
|
\fancyhead[C]{}
|
|
\hrule \medskip % Upper rule
|
|
\begin{minipage}{0.295\textwidth}
|
|
\raggedright
|
|
\footnotesize
|
|
Andrew Hayes \hfill\\
|
|
21321503 \hfill\\
|
|
a.hayes18@nuigalway.ie
|
|
\end{minipage}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\centering
|
|
\large
|
|
CT255 Assignment 2\\
|
|
\normalsize
|
|
Rainbow Tables\\
|
|
\end{minipage}
|
|
\begin{minipage}{0.295\textwidth}
|
|
\raggedleft
|
|
\today\hfill\\
|
|
\end{minipage}
|
|
\medskip\hrule
|
|
\bigskip
|
|
|
|
%-------------------------------
|
|
% CONTENTS
|
|
%-------------------------------
|
|
|
|
\section{Problem 1}
|
|
\subsection{Code}
|
|
\begin{lstlisting}[language=Java]
|
|
import java.util.HashMap;
|
|
|
|
/* CT255 Assignment 2
|
|
* This class provides functionality to build rainbow tables (with a different reduction function per round) for 8 character long strings, which
|
|
consist of the symbols "a .. z", "A .. Z", "0 .. 9", "!" and "#" (64 symbols in total).
|
|
Properly used, it creates the following value pairs (start value - end value) after 10,000 iterations of hashFunction() and reductionFunction():
|
|
start value - end value
|
|
Kermit12 lsXcRAuN
|
|
Modulus! L2rEsY8h
|
|
Pigtail1 R0NoLf0w
|
|
GalwayNo 9PZjwF5c
|
|
Trumpets !oeHRZpK
|
|
HelloPat dkMPG7!U
|
|
pinky##! eDx58HRq
|
|
01!19!56 vJ90ePjV
|
|
aaaaaaaa rLtVvpQS
|
|
aaaaaaaa klQ6IeQJ
|
|
|
|
|
|
*
|
|
* @author Michael Schukat
|
|
* @version 1.0
|
|
*/
|
|
public class RainbowTable
|
|
{
|
|
public static void main(String[] args) {
|
|
long res = 0;
|
|
|
|
// String array of the known passwords
|
|
String[] passwords = {"Kermit12", "Modulus!", "Pigtail1", "GalwayNo", "Trumpets", "HelloPat", "pinky##!", "01!19!56", "aaaaaaaa", "aaaaaaaa"};
|
|
|
|
HashMap<String, String> rainbowTable = new HashMap<>(); // declaring a HashTable that i'll use to store the password : hash pairs
|
|
|
|
|
|
// looping through the passwords array
|
|
for (String start : passwords) {
|
|
if (start.length() != 8) {
|
|
System.out.println("Input " + start + " must be 8 characters long - Exit");
|
|
}
|
|
else {
|
|
String hash = start; // declaring a String hash that will hold the final reduced hash of a given password
|
|
|
|
// hashing & reducing the start String 10000 times.
|
|
for (int i = 0; i < 10000; i++) {
|
|
hash = reductionFunction((hashFunction(hash)), i);
|
|
}
|
|
|
|
// adding the password & its hash value to the rainbowTable HashMap
|
|
rainbowTable.put(start, hash);
|
|
}
|
|
}
|
|
// printing out the contents of the rainbowTable
|
|
System.out.println(rainbowTable);
|
|
}
|
|
|
|
private static long hashFunction(String s){
|
|
long ret = 0;
|
|
int i;
|
|
long[] hashA = new long[]{1, 1, 1, 1};
|
|
|
|
String filler, sIn;
|
|
|
|
int DIV = 65536;
|
|
|
|
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
|
|
|
|
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
|
|
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
|
|
|
|
for (i = 0; i < sIn.length(); i++) {
|
|
char byPos = sIn.charAt(i); // get i'th character
|
|
hashA[0] += (byPos * 17111); // Note: A += B means A = A + B
|
|
hashA[1] += (hashA[0] + byPos * 31349);
|
|
hashA[2] += (hashA[1] - byPos * 101302);
|
|
hashA[3] += (byPos * 79001);
|
|
}
|
|
|
|
ret = (hashA[0] + hashA[2]) + (hashA[1] * hashA[3]);
|
|
if (ret < 0) ret *= -1;
|
|
return ret;
|
|
}
|
|
|
|
private static String reductionFunction(long val, int round) { // Note that for the first function call "round" has to be 0,
|
|
String car, out; // and has to be incremented by one with every subsequent call.
|
|
int i; // I.e. "round" created variations of the reduction function.
|
|
char dat;
|
|
|
|
car = new String("0123456789ABCDEFGHIJKLMNOPQRSTUNVXYZabcdefghijklmnopqrstuvwxyz!#");
|
|
out = new String("");
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
val -= round;
|
|
dat = (char) (val % 63);
|
|
val = val / 83;
|
|
out = out + car.charAt(dat);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\subsection{Output}
|
|
\includegraphics[width = 16cm]{image.png}
|
|
|
|
\bigskip
|
|
|
|
%------------------------------------------------
|
|
|
|
\section{Problem 2}
|
|
\subsection{Code}
|
|
\begin{lstlisting}[language=java]
|
|
import java.util.HashMap;
|
|
|
|
/* CT255 Assignment 2
|
|
* This class provides functionality to build rainbow tables (with a different reduction function per round) for 8 character long strings, which
|
|
consist of the symbols "a .. z", "A .. Z", "0 .. 9", "!" and "#" (64 symbols in total).
|
|
Properly used, it creates the following value pairs (start value - end value) after 10,000 iterations of hashFunction() and reductionFunction():
|
|
start value - end value
|
|
Kermit12 lsXcRAuN
|
|
Modulus! L2rEsY8h
|
|
Pigtail1 R0NoLf0w
|
|
GalwayNo 9PZjwF5c
|
|
Trumpets !oeHRZpK
|
|
HelloPat dkMPG7!U
|
|
pinky##! eDx58HRq
|
|
01!19!56 vJ90ePjV
|
|
aaaaaaaa rLtVvpQS
|
|
aaaaaaaa klQ6IeQJ
|
|
|
|
|
|
*
|
|
* @author Michael Schukat
|
|
* @version 1.0
|
|
*/
|
|
public class RainbowTable
|
|
{
|
|
public static void main(String[] args) {
|
|
long res = 0;
|
|
|
|
// String array of the known passwords
|
|
String[] passwords = {"Kermit12", "Modulus!", "Pigtail1", "GalwayNo", "Trumpets", "HelloPat", "pinky##!", "01!19!56", "aaaaaaaa", "aaaaaaaa"};
|
|
|
|
HashMap<String, String> rainbowTable = new HashMap<>(); // declaring a HashTable that i'll use to store the password : hash pairs
|
|
|
|
|
|
// looping through the passwords array
|
|
for (String start : passwords) {
|
|
if (start.length() != 8) {
|
|
System.out.println("Input " + start + " must be 8 characters long - Exit");
|
|
}
|
|
else {
|
|
String hash = start; // declaring a String hash that will hold the final reduced hash of a given password
|
|
|
|
// hashing & reducing the start String 10000 times.
|
|
for (int i = 0; i < 10000; i++) {
|
|
hash = reductionFunction((hashFunction(hash)), i);
|
|
}
|
|
|
|
// adding the password & its hash value to the rainbowTable HashMap
|
|
rainbowTable.put(start, hash);
|
|
}
|
|
}
|
|
// printing out the contents of the rainbowTable
|
|
System.out.println(rainbowTable);
|
|
|
|
// chain lookup section
|
|
// long array of the 4 hashes to be searched for
|
|
long[] hashes = {895210601874431214L, 750105908431234638L, 111111111115664932L, 977984261343652499L};
|
|
|
|
// for each loop that loops through each hash in the array of hashes
|
|
for (long hash : hashes) {
|
|
|
|
// looping 10000 times to search for the password - this will function as our max number of iterations, as 10000 iterations should just take use back to where we started.
|
|
for (int i = 0; i < 10000; i++) {
|
|
// reducing the hash
|
|
String str = reductionFunction(hash, i);
|
|
// checking if the reduced hash is a key (password) in the rainbowTable HashMap
|
|
if (rainbowTable.containsValue(str)) {
|
|
System.out.println("Found password " + str + " for hash value " + hash); // printing the found password
|
|
break; // breaking out of the for loop
|
|
}
|
|
else {
|
|
hash = hashFunction(str); // hashing str before continuing the for loop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static long hashFunction(String s){
|
|
long ret = 0;
|
|
int i;
|
|
long[] hashA = new long[]{1, 1, 1, 1};
|
|
|
|
String filler, sIn;
|
|
|
|
int DIV = 65536;
|
|
|
|
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
|
|
|
|
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
|
|
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
|
|
|
|
for (i = 0; i < sIn.length(); i++) {
|
|
char byPos = sIn.charAt(i); // get i'th character
|
|
hashA[0] += (byPos * 17111); // Note: A += B means A = A + B
|
|
hashA[1] += (hashA[0] + byPos * 31349);
|
|
hashA[2] += (hashA[1] - byPos * 101302);
|
|
hashA[3] += (byPos * 79001);
|
|
}
|
|
|
|
ret = (hashA[0] + hashA[2]) + (hashA[1] * hashA[3]);
|
|
if (ret < 0) ret *= -1;
|
|
return ret;
|
|
}
|
|
|
|
private static String reductionFunction(long val, int round) { // Note that for the first function call "round" has to be 0,
|
|
String car, out; // and has to be incremented by one with every subsequent call.
|
|
int i; // I.e. "round" created variations of the reduction function.
|
|
char dat;
|
|
|
|
car = new String("0123456789ABCDEFGHIJKLMNOPQRSTUNVXYZabcdefghijklmnopqrstuvwxyz!#");
|
|
out = new String("");
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
val -= round;
|
|
dat = (char) (val % 63);
|
|
val = val / 83;
|
|
out = out + car.charAt(dat);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
}
|
|
|
|
\end{lstlisting}
|
|
\subsection{Output}
|
|
I couldn't actually find a password match with the above code, and I'm not sure why. My current guess would be that the reduction function wasn't being called properly, as everything else \textit{seemed} to be working as expected. I didn't call the reduction more than 10,000 times as that would theoretically just lead me back to the same place in the chain. I think that my problem is with the passing of the integer \verb|i| to the reduction function, as I think that I correctly implemented the rest of the steps for performing a chain lookup - I input a hash value, reduce it, check if the reduced form is in the list of final plaintexts (the ``Values'' in the HashMap), and if so break out of the loop (but this never occurs), assigning the relevant ``Key'' from the HashMap as the original plaintext password that produced the original input hash. Otherwise, I continue until I'm back at the same place in the chain after the 10,000\textsuperscript{th} iteration, where the code gives up.
|
|
|
|
\bigskip
|
|
|
|
\includegraphics[width = 16cm]{image.png}
|
|
\end{document}
|