Reputation: 11
I am writing a program to take an MD5 hash and run it against a dictionary.txt file. if I just run a word that is in the file it cracks it fast, but if I add a special character it takes about 10 minutes to crack. Is there some way to make it run faster? If I run the MD5 hash of $hello (932d24e18f06b12e7a867425d51c909a) it takes about 10 minutes to crack.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Cracker extends verify {
private static String specialCharacters = "@#$%&";
public static void main(String[] args) {
List<String> dictionaryWords = new LinkedList<>();
try {
Scanner s = new Scanner(new File("data/dictionary.txt"));
while (s.hasNext()) {
dictionaryWords.add(s.next());
}
s.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Scanner s = new Scanner(System.in);
System.out.println("Enter the password MD5 hash to crack:");
String md5target = s.nextLine();
s.close();
long startTime = new Date().getTime();
boolean cracked = false;
System.out.println("Trying to crack it with type 1 attack");
for (String word : dictionaryWords) {
//if (MD5.md5(word).equals(md5target)) {
if (MD5.md5(word).equals(md5target)) {
System.out.println("Password is " + word);
cracked = true;
break;
}
}
if (!cracked) {
System.out.println("No matches in dictionary. Start looking for type 2 password");
outer: for (String word : dictionaryWords) {
List<String> combinationsForDictionaryWord = generateAllType2CombinationsForWord(word);
for (String generatedWord : combinationsForDictionaryWord) {
if (MD5.md5(generatedWord).equals(md5target)) {
System.out.println("Password is " + generatedWord);
cracked = true;
break outer;
}
}
}
if (!cracked) {
System.out.println("The password is not type 2 password. Not cracked");
}
}
if (cracked) {
System.out.println("Total time:" + (new Date().getTime() - startTime) / 1000.0 + " s");
}
}
private static List<String> generateAllType2CombinationsForWord(String word) {
List<String> combinations = new LinkedList<>();
List<String> oneLetterCombinations = new LinkedList<>();
// all combinations with 1 letter
for (int i = 0; i <= word.length(); i++) {
for (char ch = '0'; ch <= '9'; ch++) {
oneLetterCombinations.add(new StringBuffer(word).insert(i, ch).toString());
}
for (int j = 0; j < specialCharacters.length(); j++) {
oneLetterCombinations.add(new StringBuffer(word).insert(i, specialCharacters.charAt(j)).toString());
}
}
combinations.addAll(oneLetterCombinations);
List<String> twoLetterCombinations = new LinkedList<>();
// all combinations with two letters
for (String sourceWord : oneLetterCombinations) {
for (int i = 0; i <= sourceWord.length(); i++) {
for (char ch = '0'; ch <= '9'; ch++) {
twoLetterCombinations.add(new StringBuffer(sourceWord).insert(i, ch).toString());
}
for (int j = 0; j < specialCharacters.length(); j++) {
twoLetterCombinations
.add(new StringBuffer(sourceWord).insert(i, specialCharacters.charAt(j)).toString());
}
}
}
combinations.addAll(twoLetterCombinations);
return combinations;
}
}
'''
Upvotes: 1
Views: 83