I'm trying to brute force a Vigenere Cipher knowing only that the key length is 5+
characters and that the decrypted text has the word Hello, Andi
. So I wrote this small Java program that tries to brute-force the key through a given numbers of threads and nested while loops.
Run.java (main class)
package vignere;
import java.io.IOException;
public class Run {
public static void main(String[] args) throws IOException {
//number of threads you have and encrypted text file
Brute brute = new Brute(4, "41259.txt.enc");
Thread t1 = new Thread() {
@Override
public void run() {
try {
brute.bruteF_thread(1);
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
brute.bruteF_thread(2);
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t3 = new Thread() {
@Override
public void run() {
try {
brute.bruteF_thread(3);
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t4 = new Thread() {
@Override
public void run() {
try {
brute.bruteF_thread(4);
} catch (IOException e) {
e.printStackTrace();
}
}
};
t1.start();
t2.start();
t3.start();
t4.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And the class that handles the brute-force attack Brute.java
package vignere;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Brute {
int totalCORE;
Path path;
public Brute(int totalCORE, String string) {
this.totalCORE = totalCORE;
this.path = Paths.get(string);
}
public void bruteF_thread(int threadNR) throws IOException {
byte[] txt_enc = Files.readAllBytes(path);
byte[] plaintxt = new byte[txt_enc.length];
int shift = (256 / totalCORE) * (threadNR - 1);
int moduloNr = 0;
if (256 % totalCORE != 0 && totalCORE == threadNR) {
moduloNr = 256 % totalCORE;
}
while (shift < ((256 / totalCORE) * threadNR) + moduloNr) {
System.out.println(shift);
int shift2 = 0;
while (shift2 < 256) {
// System.out.println(shift2);
int shift3 = 0;
while (shift3 < 256) {
int shift4 = 0;
while (shift4 < 256) {
int i = 0;
while (i < 40) {
// first char by shift
int charNr = txt_enc[i] & 0xff;
charNr = charNr + shift;
charNr = charNr % 256;
plaintxt[i] = (byte) charNr;
i++;
// second by shift2
charNr = txt_enc[i] & 0xff;
charNr = charNr + shift2;
charNr = charNr % 256;
plaintxt[i] = (byte) charNr;
i++;
// third one by shift3
charNr = txt_enc[i] & 0xff;
charNr = charNr + shift3;
charNr = charNr % 256;
plaintxt[i] = (byte) charNr;
i++;
// fourth by shift4
charNr = txt_enc[i] & 0xff;
charNr = charNr + shift4;
charNr = charNr % 256;
plaintxt[i] = (byte) charNr;
i++;
}
// after the array is filled
// convert it to string
String aString2 = new String(plaintxt);
if (aString2.indexOf("Andi") > 0) {
System.out.println("The code you are looking for is: " + shift + "-" + shift2 + "-" + shift3
+ "-" + shift3);
System.out.println(aString2);
// System.exit(1);
}
shift4++;
}
shift3++;
}
shift2++;
}
shift++;
System.out.println(shift++);
}
}
}
And while I know that a lot of computation is required I would like to know if there is any way I could optimise this code, as it's painfully slow.