How to get the RSA public-key from private-key Object in Java

烈酒焚心 提交于 2019-11-30 16:32:29

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);

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!