12

I am looking for a Java function that will get an RSA PrivateKey and will return the correct RSA PublicKey?

Alternatively, is there a function that will tell us if the RSA PrivateKey/PublicKey is valid?

Petey B
  • 11,439
  • 25
  • 81
  • 101
DasDas
  • 571
  • 3
  • 9
  • 32
  • 1
    Keep cool. A forum is quite differend from a live chat. Keep always in mind the users are here with their own free will and whenever they want and can. – Reporter Jul 05 '12 at 13:33
  • Define what you mean by "valid". – President James K. Polk Jul 06 '12 at 10:32
  • Besides the answers given, if you can always perform a sign/verify (on any value) to see if the keys match. Note that once in a while this is troublesome, e.g. if a use count is kept for a private key (some HSM's and smart cards do). Comparing just the modulus or a hash over the modulus is fine too, the modulus should be unique for each key pair. No need for the public exponent. – Maarten Bodewes Nov 05 '14 at 21:29

5 Answers5

13

If you have your private key as an RSAPrivateCrtKey object, you can get the public exponent as well as modulous.

Then you could create the public key like so:

RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(modulus, exponent);   
try {   
     KeyFactory keyFactory = KeyFactory.getInstance("RSA");   

     PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);   
} catch (Exception e) {   
     e.printStackTrace();   
} 
Petey B
  • 11,439
  • 25
  • 81
  • 101
  • The constructor is actually RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) http://docs.oracle.com/javase/7/docs/api/java/security/spec/RSAPublicKeySpec.html – Eric Woodruff Dec 01 '13 at 08:57
6

I can't think of any good reason you'd need this. But here it is:

static boolean isValidRSAPair(KeyPair pair)
{
  Key key = pair.getPrivate();
  if (key instanceof RSAPrivateCrtKey) {
    RSAPrivateCrtKey pvt = (RSAPrivateCrtKey) key;
    BigInteger e = pvt.getPublicExponent();
    RSAPublicKey pub = (RSAPublicKey) pair.getPublic();
    return e.equals(pub.getPublicExponent()) && 
      pvt.getModulus().equals(pub.getModulus());
  }
  else {
    throw new IllegalArgumentException("Not a CRT RSA key.");
  }
}
erickson
  • 265,237
  • 58
  • 395
  • 493
1

As others have noted, if you have a RSA CRT KEY, then you can extract the public key from that. However it is actually not possible to retrieve a public key from a pure private key.

The reason for that is easy: When generating RSA keys, there is actually no difference between the private and the public key. One is choosen to be private, the remaining one is public then.

So if you could compute the public key from a pure private key, you could by Definition compute the private key from the public key...

If you have both, you can actually easily test if they match:

RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
return rsaPublicKey.getModulus().equals( rsaPrivateKey.getModulus() )
  && BigInteger.valueOf( 2 ).modPow(
  rsaPublicKey.getPublicExponent().multiply( rsaPrivateKey.getPrivateExponent() )
    .subtract( BigInteger.ONE ), 
  rsaPublicKey.getModulus() ).equals( BigInteger.ONE );
Steffen Heil
  • 4,286
  • 3
  • 32
  • 35
0

If you have an object of type RSAPrivateKey then you need to do two things:

  1. Get the modulus. Easy: privateKey.getModulus()
  2. Compute the public exponent. This is a little tricky but not impossible. See the definition of public exponent. Usually, the public exponent is 65537.

After getting modulus and public exponent, you can follow PeteyB's answer.

HRJ
  • 17,079
  • 11
  • 56
  • 80
-4

AFAIK you cannot derive the other key of an RSA key pair, given one key. That would be equivalent to breaking RSA.

For testing a pair, just encrypt something using one key and decrypt it using the other to see if you get the original result back.

Sfynx
  • 365
  • 2
  • 4
  • thanks so much! can you be a lil more clear about the second answer? do you have the actual java code for doing it? – DasDas Jul 05 '12 at 13:58
  • 3
    I think this is wrong. According to http://stackoverflow.com/questions/5244129/openssl-use-rsa-private-key-to-generate-public-key you can get public RSA key from the private key. – MK. Jul 05 '12 at 13:58
  • MK, do you know how to do it with Java? – DasDas Jul 05 '12 at 14:07
  • 5
    @MK That is because the public key is included in the private key. – Mark Rotteveel Jul 05 '12 at 17:51
  • Deriving the publick key from a private key is certainly possible. See my answer. – HRJ Jul 07 '13 at 13:03