So , I have sort of came up with a way to directly bypass the RSA encryption with relatively little computational effort. So in the form of a MITM attack (man in the middle) where all he knows is the public key , how do you effectively decrypt there message? you would assume you would need to know the private key in order to decrypt using the function encrypted_var^privatekey mod sum_of_primes. However that takes effort , a lot of effort , especially with the banks using 2048bit (671 digit long) codes. So that obviously wont work unless you have a couple of super computers to hand however what if you pregenerate the keyset IE you have monitored the traffic and you know what the public key is , you then take this and you apply it to every character in the ascii key set. so a b c d e f g on and on until you have the value for each , during the transmission you then check this against the message they are sending and you can effectively decrypt using fairly little computational effort, if they are sending a relatively long message say a few thousand characters like a resume then you will use less effort calculating the values than they did actually encrypting their data.
So using my little RSA algorithm , it doesnt use very large numbers as I didnt want to use biginteger however it is still viable to use to test.
Here is the code for calculating an RSA encryption from the given keys:
[spoiler]
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
public class Encryptor {
public Encryptor() {
long[] key = new long[4];
boolean newkeys = JOptionPane.showConfirmDialog(null,
"Generate new keys?") == JOptionPane.YES_OPTION;
if (newkeys) {
key = calculate_key(generateprimelong(), generateprimelong());
JOptionPane.showMessageDialog(null, "Your public key is: " + key[0] + "," + key[1]);
JOptionPane.showMessageDialog(null, "Your private key is: " + key[2] + "," + key[3]);
}
else{
}
if (JOptionPane.showConfirmDialog(null,
"Are you decrypting?")== JOptionPane.YES_OPTION) {
if(!newkeys){
String privatekey = JOptionPane.showInputDialog("Please enter you private key in the form a,b");
String[] pks = privatekey.split(",");
key[2] = Long.parseLong(pks[0]);
key[3] = Long.parseLong(pks[1]);
}
String decryptlocation = JOptionPane
.showInputDialog("Please enter the file location of your encrypted text file");
try {
decrypt(key[2],key[3],read(decryptlocation));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
if(!newkeys){
String publickey = JOptionPane.showInputDialog("Please enter your public key in the form a,b");
String[] pls = publickey.split(",");
key[0] = Long.parseLong(pls[0]);
key[1] = Long.parseLong(pls[1]);
}
String fileloc = JOptionPane
.showInputDialog("Enter the location of your unencrypted text file");
try {
String data = readstring(fileloc);
encrypt(key[0],key[1],data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Encryptor();
}
private static Random r = new Random();
public static long generateprimelong() {
boolean testing = true;
while (testing) {
long num = Math.abs(r.nextLong()) / 900000000000000l;
if (!isprime(num)) {
continue;
}
testing = false;
return num;
}
return 0l;
}
public static boolean isprime(long n) {
if (n <= 3) {
if (n <= 1) {
return false;
} else {
return true;
}
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
for (int i = 5; i < Math.sqrt(n) + 1; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
public static int generateprimeshort(int max) {
boolean testing = true;
while (testing) {
int num = Math.abs(r.nextInt(max));
if (!isprime(num)) {
continue;
}
testing = false;
return num;
}
return 0;
}
public long[] calculate_key(long P, long Q) {
long n = P * Q;
long tonient_n = (P - 1) * (Q - 1);
long e = generateprimeshort(Math.abs((int) (Math.sqrt(n))));
long d = findInverse(e, tonient_n);
long[] keys = new long[4];
keys[0] = n;
keys[2] = n;
keys[1] = e;
keys[3] = d;
// encrypt(n, e,
// "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
return keys;
}
public static long findInverse(long a, long b) {
long calculate = b;
long x = 0, y = 1, lastx = 1, lasty = 0;
while (b != 0) {
long quotient = a / b;
long temp = a;
a = b;
b = temp % b;
temp = x;
x = lastx - quotient * x;
lastx = temp;
temp = y;
y = lasty - quotient * y;
lasty = temp;
}
// int[] coefficients = {lastx, lasty, a};
return calculate + lastx;
}
public void encrypt(long a, long b, String information) {
long[] value = new long[information.length()];
for (int i = 0; i < information.length(); i++) {
char letter = information.charAt(i);
int lettercode = letter;
value[i] = powmod(lettercode, b, a);
}
try {
write(value);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void decrypt(long a , long b , long[] data){
String datastring= "";
for(int i = 0; i < data.length;i++){
long value = powmod(data[i],b,a);
System.out.println(value);
datastring += (char)value;
}
try {
writestring(datastring);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static long powmod(long base, long exponent, long modulus) {
if (exponent < 0)
throw new IllegalArgumentException("exponent < 0");
long result = 1;
while (exponent > 0) {
if ((exponent & 1) != 0) {
result = (result * base) % modulus;
}
exponent >>>= 1;
base = (base * base) % modulus;
}
return result;
}
public static void write(long[] content) throws IOException {
File file = new File("Encrypted.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
for (int i = 0; i < content.length; i++) {
try {
bw.write(Long.toString(content[i]) + ";");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
bw.close();
}
public static void writestring(String content) throws IOException {
File file = new File("unencrypted.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
}
public static long[] read(String location) throws IOException {
File file = new File(location);
if (!file.exists()) {
System.out.println("NO FILE LOCATED");
return null;
}
FileReader fr = new FileReader(file.getAbsoluteFile());
BufferedReader br = new BufferedReader(fr);
String filedata = br.readLine();
String[] info = filedata.split(";");
long[] data = new long[info.length];
for (int i = 0; i < info.length; i++) {
data[i] = Long.parseLong(info[i]);
}
return data;
}
public static String readstring(String location) throws IOException {
File file = new File(location);
if (!file.exists()) {
return null;
}
FileReader fr = new FileReader(file.getAbsoluteFile());
BufferedReader br = new BufferedReader(fr);
String filedata = br.readLine();
return filedata;
}
}
[/spoiler]
Here are the keys it generated for me public key: modulo = 4127353, exponent = 1193 private key: inverse modulo of the totient of n and e = 3853577.
So ill encrypt some data , just a simple sentence.
Hi there my pseudonym is lcass <- hazzah , so what does this code output.
tada:
110284;3066158;2777967;1857537;3770054;2342914;1419964;2342914;2777967;2041712;179304;2777967;2630803;1377978;2342914;2399661;3956477;461248;3312036;179304;2041712;2777967;3066158;1377978;2777967;1251139;133099;3923355;1377978;1377978;
So the algorithm works , it provides a seemingly impossible to solve output with only the public key known. The code to crack this is horrendously simple , a primary school student could learn to do write it.
So whats the output from my software (currently)
[spoiler]
1
3361614
524989
3812176
3017243
3757682
1115560 a
481481
1198840
1406822
3021519
1123717
4100787
2196864
3214222
3536678
1087018
3184147
2770508
1298307
1847552
97787
1113478
748930
3280713
3026690
1881143 e
2093244
2655181
1019726
2347297
2777967
2787154 !
3585267 "
1446638 #
4117764 $
2058807 %
2308059 &
3595366 '
3595296 (
2589501 )
2548941 *
2037439 +
3245886 ,
65685 -
3307204 .
2032884 /
2535374 0
2891746 1
1294485 2
4030257 3
2720298 4
3932494 5
2274088 6
2906303 7
3734352 8
2899859 9
3844924 :
3708039 ;
1691850 <
1540648 =
4100487 >
12516 ?
2917410 @
1245075 A
1082729 B
2536003 C
245638 D
2568999 E
1390894 F
1300269 G
110284 H
3676029 I
3829978 J
2084963 K
3037529 L
361130 M
1706999 N
2292876 O
1653140 P
2865999 Q
1658786 R
3976913 S
1701301 T
517277 U
1186285 V
1634613 W
2858905 X
969002 Y
2484796 Z
2554933 [
2042631 \
1319523 ]
1514145 ^
2744424 _
1934813 `
3923355 a
2194206 b
133099 c
3956477 d
2342914 e
57002 f
3985480 g
3770054 h
3066158 i
3197498 j
2733213 k
1251139 l
2041712 m
3312036 n
461248 o
2630803 p
3048649 q
1419964 r
1377978 s
1857537 t
2399661 u
1783764 v
979268 w
2796608 x
179304 y
3558530 z
264055 {
1616622 |
3342005 }
3851695 ~
3002970
596143 ?
641750 ?
3675516 ?
2708598 ?
2466850 ?
2794255 ?
3185283 ?
3995503 ?
1261787 ?
3550272 ?
388952 ?
3754967 ?
1660984 ?
3181595 ?
3571870 ?
3214743 ?
1009857 ?
2037687 ?
739687 ?
3605628 ?
1442762 ?
2275239 ?
1077450 ?
1469684 ?
2982160 ?
2604959 ?
1325930 ?
1042997 ?
478427 ?
3772141 ?
2499365 ?
1739907 ?
1904052
3995565 ¡
1310958 ¢
2156012 £
4007602 ¤
2012745 ¥
3352930 ¦
2850885 §
1047128 ¨
4102346 ©
2894707 ª
3413089 «
304802 ¬
89407
3038244 ®
978002 ¯
1866876 °
1262062 ±
517803 ²
3879004 ³
401403 ´
3087098 µ
3009749 ¶
2394874 ·
110336 ¸
2975568 ¹
2938080 º
1206767 »
3744546 ¼
16348 ½
3582968 ¾
1465072 ¿
1115779 À
4005093 Á
1295531 Â
1784565 Ã
2642477 Ä
124753 Å
1759821 Æ
1950156 Ç
1072558 È
1039698 É
669182 Ê
2326498 Ë
2230850 Ì
244389 Í
1630834 Î
1076201 Ï
3803297 Ð
3933522 Ñ
1012112 Ò
2918393 Ó
62403 Ô
4009371 Õ
3388657 Ö
3908357 ×
3506345 Ø
1058706 Ù
2174467 Ú
2945588 Û
100071 Ü
1368753 Ý
2650703 Þ
3993333 ß
3012647 à
370101 á
2693719 â
3591687 ã
442983 ä
471566 å
2808120 æ
3444868 ç
502782 è
3314998 é
50533 ê
324629 ë
285518 ì
430620 í
2048694 î
101233 ï
1163385 ð
3946168 ñ
459242 ò
3794920 ó
2138401 ô
4082221 õ
1811825 ö
1770521 ÷
2344279 ø
1681848 ù
3878013 ú
2054449 û
994136 ü
3771897 ý
1568825 þ
1416965 ÿ
[/spoiler]
checking it the output from my RSA “H” is the same as the interpreter.
Now to get it to decrypt an entire message.
And whats the output?
Hi there my pseudonym is lcass
Here is the cracking code.
[spoiler]
import javax.swing.JOptionPane;
public class RSA {
int[] ASCII_CHAR_SET = new int[256];//I dont know the actual length so just have it like this
char[] DATA_COMPARE = new char[256];//the data to reference , random access abit easier than char casting
public RSA(){
System.out.println("RSA HACKER STARTED");
String key = JOptionPane.showInputDialog("What is the public key , enter in the form n,e");
String[] public_key = key.split(",");//split string where public_key[0] = n and public_key[1] = e
System.out.println("Key accepted , preparing to generate keyset");
//convert both to their integer counterparts
int sum_n = Integer.valueOf(public_key[0]);
int exponent = Integer.valueOf(public_key[1]);
//perform the key set generation
for(int i =0; i < ASCII_CHAR_SET.length;i++){
ASCII_CHAR_SET[i] = powmod(i,exponent,sum_n);
char current = (char)i;//should be able to convert from int to char
DATA_COMPARE[i] = current;//fairly simple assign the character to this
System.out.println(ASCII_CHAR_SET[i] + " " + current);
}
String data = JOptionPane.showInputDialog("What is the data you wish to decrypt");
String[] seperated_data = data.split(";");
String output = "";
for(int i = 0;i < seperated_data.length;i++){
int value = Integer.valueOf(seperated_data[i]);
for(int j = 0;j < ASCII_CHAR_SET.length;j++){
if(ASCII_CHAR_SET[j] == value){
output+= DATA_COMPARE[j];
break;
}
}
}
System.out.println(output);
}
public static int powmod(long base, long exponent, long modulus) {
if (exponent < 0)
throw new IllegalArgumentException("exponent < 0");
long result = 1;
while (exponent > 0) {
if ((exponent & 1) != 0) {
result = (result * base) % modulus;
}
exponent >>>= 1;
base = (base * base) % modulus;
}
return (int)result;
}//very large numbers so a very annoying method must be required.
public static void main(String[] args){
new RSA();//static tags become annoying after some time
}
}
[/spoiler]
Enjoy.