如何从 RSA 密码系统中的私钥对象
java.security.PublicKey
中获取相关的公钥对象 java.security.PrivateKey
。
Java 能够使用模数和指数创建公钥:
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
kf.generatePublic(keySpec);
所以我们需要从私钥中提取这些值:
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);
RSAPrivateKeySpec
-对象现在包含我们需要的模数,但指数不是我们需要的公钥。
对于公钥,指数通常为 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);
您需要将私钥转换为 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);
}
如果转换失败,您可以尝试猜测公共指数,并使用所有 x 的标准 RSA 关系 (xe)d = x mod N 来检查您的猜测。为了猜测 e,请在方程中尝试一些随机的 x 值,看看该关系是否始终成立。该技术只能产生概率答案。有关在未知时查找公共指数的更多详细信息,请参阅有关加密货币的答案。
感谢@SamGinrich 提供的有用建议。