import java.lang.Math; import java.math.BigInteger; import java.util.Random; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class RSA { final static BigInteger m = new BigInteger("91011121314151617181920212223242526272829",10); BigInteger p = new BigInteger("0",10); BigInteger q = new BigInteger("0",10); BigInteger phi = new BigInteger("0",10); BigInteger e = new BigInteger("0",10); BigInteger sha = new BigInteger("0",10); BigInteger n = new BigInteger("0",10); BigInteger d = new BigInteger("0",10); BigInteger encrypted = new BigInteger("0",10); BigInteger decrypted = new BigInteger("0",10); //Generates a PrimNumber private BigInteger genPrim(int bitlen){ BigInteger p = BigInteger.probablePrime(bitlen, new Random()); if(!p.isProbablePrime(100000)){ throw new RuntimeException(); } return p; } //Generates an E using phi private void genE(BigInteger phi){ e = genPrim(256); if(!phi.gcd(e).equals(BigInteger.ONE)){ genE(phi); } } //Encrypt-Funktion public void encrypt(){ q = genPrim(256); //get q p = genPrim(256); //get p if(p.equals(q)){ //ensure p!=q encrypt(); } phi = p.subtract(BigInteger.ONE).multiply( q.subtract(BigInteger.ONE)); //phi=(p - 1)(q - 1) n = p.multiply(q); //n = p*q genE(phi); //get e SHA256(); //calculate Hash of m encrypted = expModuloN(sha, e, n); // hash^e mod n } //Decrypt Function (you need 2 run encrypt first) public void decrypt(){ d = extEuklid(e, phi); //calculate d decrypted = expModuloN(encrypted, d, n); //decrypt } //extended Euklid-Algorithm private BigInteger extEuklid(BigInteger a, BigInteger b){ //Ancor if(b.equals(BigInteger.ZERO)){ return BigInteger.ONE; } //Initialize vars BigInteger x1 = new BigInteger("0",10); BigInteger x2 = new BigInteger("1",10); BigInteger y = new BigInteger("1",10); BigInteger y1 = new BigInteger("1",10); BigInteger y2 = new BigInteger("0",10); BigInteger r = new BigInteger("0",10); BigInteger q = new BigInteger("0",10); BigInteger x = new BigInteger("0",10); while(b.compareTo(BigInteger.ZERO) == 1){ q = a.divide(b); r = a.mod(b); x = x2.subtract(q.multiply(x1)); y = y2.subtract(q.multiply(y1)); a = b; b = r; x2 = x1; x1 = x; y2 = y1; y1 = y; } if(x2.compareTo(BigInteger.ZERO) == -1){ x2 = phi.add(x2); } return x2; //only x2 is needed } //Efficient m^e mod n private BigInteger expModuloN(BigInteger m, BigInteger e, BigInteger n){ BigInteger b = m; BigInteger r = BigInteger.ONE; for(int i = 0; i <= e.bitLength(); i++){ if(e.testBit(i)){ r = r.multiply(b).mod(n); } b = b.multiply(b).mod(n); } return r; } //Converts a byte to a HexString public String BytetoHex(byte b) { int value = (b & 0x7F) + (b < 0 ? 128 : 0); String ret = (value < 16 ? "0" : ""); ret += Integer.toHexString(value).toUpperCase(); return ret; } //Converts SHA-byte-array to HexString public String SHAtoHex(byte[] d) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < d.length; i++) { buf.append(BytetoHex(d[i])); } return buf.toString(); } //Calculates SHA256 of m private void SHA256(){ try { MessageDigest l = MessageDigest.getInstance("SHA-256"); l.reset(); l.update(m.toByteArray()); sha = new BigInteger(SHAtoHex(l.digest()), 16); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(); } } public static void main(String[] args) { RSA r = new RSA(); r.encrypt(); //calculate all r.decrypt(); //Print all System.out.println("\nKey public:"); System.out.println("\t e: " + r.e); System.out.println("\t n: " + r.n); System.out.println("\nKey private:"); System.out.println("\t d: " + r.d); System.out.println("\nHashvalue:"); System.out.println("\t sha: " + r.sha); System.out.println("\nSignature:"); System.out.println("\t Enc.: " + r.encrypted); System.out.println("\nDecrypted:"); System.out.println("\t Dec.: " + r.decrypted); System.out.println("\nSHA = Decrypted:"); System.out.println(r.decrypted.equals(r.sha)); } }