import java.math.BigInteger; import java.util.Random; import java.io.*; public class RSA { private BigInteger p; private BigInteger q; private BigInteger n; private BigInteger z; private BigInteger e; private BigInteger d; // Følger beskrivelsen af RSA fra: // "Computer networking: A topdown approach feat, the internet" // James Kurose. public RSA() {} // Gemmer de forskellige tal. // Et tal per linie i en veldefineret rækkefølge. public void Save(String file) { PrintWriter out; try { out = new PrintWriter(new FileWriter(file, false)); } catch (IOException e) { System.out.println("Save error."); return; } out.println(p.toString()); out.println(q.toString()); out.println(n.toString()); out.println(z.toString()); out.println(e.toString()); out.println(d.toString()); out.close(); } // Loader en tidligere gemt nøgle. // Returnerer true hvis det lykkedes. public boolean Load(String file) { BufferedReader in; try { in = new BufferedReader(new FileReader(file)); } catch (FileNotFoundException e){ System.out.println("File not found."); return false; } try { p = new BigInteger( in.readLine()); q = new BigInteger( in.readLine()); n = new BigInteger( in.readLine()); z = new BigInteger( in.readLine()); e = new BigInteger( in.readLine()); d = new BigInteger( in.readLine()); in.close(); } catch (IOException e) { System.out.println("File read error."); return false; } return true; } // Bruger den offentlige nøgle til kryptering af strengen str. public String[] EncryptPublic(String str) { return Encrypt(str, e, n); } // Bruger den private nøgle til kryptering af strengen str. public String[] EncryptPrivate(String str) { return Encrypt(str, d, n); } // Bruger nøglen key med modulos mod til kryptering af strengen str. public static String[] Encrypt(String str, BigInteger key, BigInteger mod) { byte[] bytes; int i = 0; String[] res = new String[(str.length() / 100) + 1]; BigInteger bi; // Tag bidder af teksten, med 100 tegn i hver. while (i + 100 < str.length() ) { bytes = str.substring(i, i + 100).getBytes(); bi = new BigInteger(bytes); bi = bi.modPow(key, mod); res[i / 100] = bi.toString(); i += 100; } // Tag resten af strengen, og fyld ud med 0 som padding i de ikke benyttede bytes. byte[] tmp = new byte[100]; bytes = str.substring(i, str.length()).getBytes(); for (int j = 0 ; j < bytes.length ; j++) { tmp[j] = bytes[j]; } bi = new BigInteger(tmp); bi = bi.modPow(key, mod); res[i / 100] = bi.toString(); return res; } // Bruger den offentlige nøgle til dekryptering af cipher. public String DecryptPublic(BigInteger cipher) { return Decrypt(cipher, e, n); } // Bruger den private nøgle til dekryptering af cipher. public String DecryptPrivate(BigInteger cipher) { return Decrypt(cipher, d, n); } // Bruger key og mod til dekryptering af cipher. public static String Decrypt(BigInteger cipher, BigInteger key, BigInteger mod) { BigInteger clear = cipher.modPow(key, mod); return new String(clear.toByteArray()); } // Generer et RSA-nøglesæt. verbose afgør om der skal udskrives // information om arbejdet til brugeren. public void GenerateKeys(boolean verbose) { if (verbose) System.out.print("Calculating p... "); do { p = new BigInteger(1024, new Random(System.currentTimeMillis())); } while (!p.isProbablePrime(10)); if (verbose) System.out.println("done!"); if (verbose) System.out.print("Calculating q... "); do { q = new BigInteger(1024, new Random(System.currentTimeMillis())); } while (!q.isProbablePrime(10)); if (verbose) System.out.println("done!"); if (verbose) System.out.print("Calculating n = p*q... "); n = p.multiply(q); if (verbose) System.out.println("done!"); if (verbose) System.out.print("Calculating z = (p-1)*(q-1)... "); z = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE)); if (verbose) System.out.println("done!"); if (verbose) System.out.print("Calculating e... "); do { e = new BigInteger(1024, new Random(System.currentTimeMillis())); if ( e.min(n).equals(n)) continue; if (!e.gcd(z).equals(BigInteger.ONE)) continue; } while (!e.isProbablePrime(10)); if (verbose) System.out.println("done!"); if (verbose) System.out.print("Calculating d = inv(e) mod n... "); d = e.modInverse(z); if (verbose) System.out.println("done!"); } public BigInteger GetPublicKey() { return e; } public BigInteger GetModulos() { return n; } }