How to get the related public-key object java.security.PublicKey
out of a private-key Object java.security.PrivateKey
in the RSA cryptosystem.
问题:
回答1:
Java is able to create a public key by using the modulus and exponent:
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
kf.generatePublic(keySpec);
So we need to extract these values out of the private key:
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);
The RSAPrivateKeySpec
-Object now contains the modulus we need, but the exponent is not the one we need for the public key.
For the public key the exponent is commonly at 65537: http://en.wikipedia.org/wiki/65537_(number)
Therefore we can now create the public key:
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(priv.getModulus(), BigInteger.valueOf(65537));
PublicKey publicKey = kf.generatePublic(keySpec);
回答2:
You need to cast the private key into an RsaPrivateCrtKey. If the cast succeeds, you can extract the public key. If the cast fails, strictly speaking you don't have enough information.
public static RSAPublicKeySpec getPublicKeySpec(PrivateKey priv) {
RSAPrivateCrtKey rsaCrtKey = (RSAPrivateCrtKey) priv; // May throw a ClassCastException
return new RSAPublicKeySpec(rsaCrtKey.getModulus(), rsaCrtKey.getPublicExponent());
}
If the cast fails, you can attempt to guess the public exponent, and check your guess by using the standard RSA relation (xe)d = x mod N for all x. For your guess of e try random x values in the equation and see if the relation always holds. This technique can only yield a probabilistic answer however.