Skip to content

Instantly share code, notes, and snippets.

@olofmagn
Last active December 15, 2020 09:58
Show Gist options
  • Save olofmagn/cb8ecc7fc4ff6c107977b489c7ac43f7 to your computer and use it in GitHub Desktop.
Save olofmagn/cb8ecc7fc4ff6c107977b489c7ac43f7 to your computer and use it in GitHub Desktop.
import java.io.BufferedReader;
import java.io.FileReader;
import java.math.BigInteger;
public class AttackRSA {
public static void main(String[] args) {
String filename = "input.txt";
BigInteger[] N = new BigInteger[3];
BigInteger[] e = new BigInteger[3];
BigInteger[] c = new BigInteger[3];
try {
BufferedReader br = new BufferedReader(new FileReader(filename));
for (int i = 0; i < 3; i++) {
String line = br.readLine();
String[] elem = line.split(",");
N[i] = new BigInteger(elem[0].split("=")[1]);
e[i] = new BigInteger(elem[1].split("=")[1]);
c[i] = new BigInteger(elem[2].split("=")[1]);
}
br.close();
} catch (Exception err) {
System.err.println("Error handling file.");
err.printStackTrace();
}
BigInteger m = recoverMessage(N, e, c);
System.out.println("Recovered message: " + m);
System.out.println("Decoded text: " + decodeMessage(m));
}
public static String decodeMessage(BigInteger m) {
return new String(m.toByteArray());
}
/**
* Tries to recover the message based on the three intercepted cipher texts.
* In each array the same index refers to same receiver. I.e. receiver 0 has
* modulus N[0], public key d[0] and received message c[0], etc.
*
* @param N The modulus of each receiver.
* @param e The public key of each receiver (should all be 3).
* @param c The cipher text received by each receiver.
* @return The same message that was sent to each receiver.
*/
private static BigInteger recoverMessage(BigInteger[] N, BigInteger[] e,
BigInteger[] c) {
//CRT!
//Reference: https://www.freecodecamp.org/news/how-to-implement-the-chinese-remainder-theorem-in-java-db88a3f1ffe0/
//Initalize sum of the array
BigInteger sum = BigInteger.ZERO;
//Find the product of all numbers in the first array
BigInteger[] products = new BigInteger[3];
products[0] = N[1].multiply(N[2]);
products[1] = N[0].multiply(N[2]);
products[2] = N[0].multiply(N[1]);
// Find the inverse using the extended euclidean algorithm.
for (int i = 0; i < N.length - 1; i++) {
BigInteger[] eea = EEA.EEA(products[i], N[i]);
BigInteger mod = eea[1].mod(N[i]);
sum = sum.add(c[i].multiply(mod).multiply(products[i]));
}
BigInteger product = BigInteger.ONE;
// Muliply all the N values together
for (int i = 0; i < N.length - 1; i++) {
product = product.multiply(N[i]);
}
BigInteger mod = sum.mod(product);
//Return the CubeRoot of the mod
return CubeRoot.cbrt(mod);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment