如何从Java中的私钥对象获取RSA公钥

Den*_*hel 1 java cryptography rsa public-key private-key

如何从RSA密码系统中的java.security.PublicKey私钥对象java.security.PrivateKey中获取相关的公钥对象.

Jam*_*olk 6

您需要将私钥转换为 RsaPrivateCrtKey。如果转换成功,您可以提取公钥。如果演员失败,严格来说,你没有足够的信息。

public static RSAPublicKey getPublicKeySpec(PrivateKey priv) throws NoSuchAlgorithmException, InvalidKeySpecException {
    RSAPrivateCrtKey rsaCrtKey = (RSAPrivateCrtKey) priv; // May throw a ClassCastException
    RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(rsaCrtKey.getModulus(), rsaCrtKey.getPublicExponent());
    return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(rsaPublicKeySpec);
}
Run Code Online (Sandbox Code Playgroud)

如果转换失败,您可以尝试猜测公共指数,并使用所有 x 的标准 RSA 关系 (x e ) d = x mod N 来检查您的猜测。为了猜测 e,请在方程中尝试一些随机的 x 值,看看该关系是否始终成立。该技术只能产生概率答案。有关在未知时查找公共指数的更多详细信息,请参阅crypto 上的此答案

感谢@SamGinrich 提供的有用建议。


Den*_*hel 5

Java能够通过使用模数和指数来创建公钥:

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
kf.generatePublic(keySpec);
Run Code Online (Sandbox Code Playgroud)

所以我们需要从私钥中提取这些值:

KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);
Run Code Online (Sandbox Code Playgroud)

RSAPrivateKeySpec-object现在包含我们需要的模数,但指数不为我们所需要的公共密钥之一.

对于公钥,指数通常为65537:http://en.wikipedia.org/wiki/65537_(number )

因此我们现在可以创建公钥:

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);
Run Code Online (Sandbox Code Playgroud)

  • RSA的公钥指数不固定为65537,这只是它的最常见值.由于私钥指数取决于公钥指数,因此该解决方案不适用于所有情况. (4认同)
  • 仅转换为“RSAPrivateKey”有什么问题(当然是在验证它*是*“RSAPrivateKey”之后)? (2认同)