Below is my implementation of the RSA algorithm. Actually I'm choosing the private key (d) instead of public key (e) and computing the public key.It is working fine but
I want to know if this is a safe implementation? and also Is any part in the code could lead to factorization of the modulus (n), thereby breaking the key?
As I did some work on it, I think the way I'm calculating (e and d) that could leads to factorization of the modulus(n) but I'm not sure. I read some research work on vulnerable class of exponents in RSA and from there I got public exponent satisfying an equation:
eX - NY = (ap + bq)Z with q>a>0, b=[ap/q]
Using the continued fraction algorithm and the Elliptic Curve Method of factorization, we can show that such exponents yield the factorization of the RSA modulus.
So question is that IS any part in code could lead to factorization of the modulus(n), thereby breaking the key? If yes then which part?
import java.math.*;
import java.security.*;
import java.util.*;
public class RSAKeyGenerator
{
public static int KEY_SIZE = 2048;
public static void main(String [] args)
{
try
{
//select size of each prime factor whose product will be atleast the given keysize.
int factor_size = KEY_SIZE/2;
Random rnd = new SecureRandom();
BigInteger p = BigInteger.probablePrime(factor_size, rnd);
BigInteger q = BigInteger.probablePrime(factor_size, rnd);
//compute N = p * q
BigInteger N = p.multiply(q);
//compute euler phi = (p-1) * (q-1)
BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
//select d size
int d_size = KEY_SIZE / 5;
//compute d
BigInteger d = BigInteger.probablePrime(d_size, rnd);
//make sure d is a coprime to euler phi.
while (phi.gcd(d).compareTo(BigInteger.ONE) > 0)
{
//select another d
d = BigInteger.probablePrime(d_size, rnd);
}
// compute e = d^-1 mod phi
BigInteger e = d.modInverse(phi);
BigInteger plaintext = BigInteger.probablePrime(d_size, rnd);
BigInteger ciphertext = plaintext.modPow(e, N);
BigInteger decryptedvalue = ciphertext.modPow(d, N);
if(decryptedvalue.compareTo(plaintext) == 0)
{
System.out.println("decrypted values matches original plain text. these are proper RSA keys");
}
else
{
System.out.println("something wrong... decrypted value does not match. try again!");
return;
}
catch (Throwable th)
{
}
}