我正在寻找一个 Java 函数,它将获取 RSA 私钥并返回正确的 RSA 公钥?
或者,是否有一个函数可以告诉我们 RSA 私钥/公钥是否有效?
如果您将私钥作为 RSAPrivateCrtKey 对象,您可以获得公共指数以及模数。
然后你可以像这样创建公钥:
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();
}
我想不出您需要这个的任何充分理由。但这里是:
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.");
}
}
正如其他人所指出的,如果您有
RSA CRT KEY
,那么您可以从中提取公钥。然而,实际上“不可能”从纯私钥中检索公钥。
原因很简单:生成 RSA 密钥时,私钥和公钥实际上没有区别。选择一个是私有的,剩下的一个是公开的。
因此,如果您可以从纯私钥计算公钥,那么您可以根据定义从公钥计算私钥......
如果两者都有,您实际上可以轻松测试它们是否匹配:
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 );
RSAPrivateKey
的对象,那么您需要做两件事:
获取模数。简单:
privateKey.getModulus()
65537
。
public PublicKey generatePublicKey(String privateKey) {
try {
KeyFactory kf = KeyFactory.getInstance(ALGORITHM);
byte[] encodedPv = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec keySpecPv = new PKCS8EncodedKeySpec(encodedPv);
RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) kf.generatePrivate(keySpecPv);
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent());
return kf.generatePublic(publicKeySpec);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
首先,我们应该将Base64私钥转换为Byte[],并且我们必须使用这两行找到PrivateKey:
PKCS8EncodedKeySpec keySpecPv = new PKCS8EncodedKeySpec(encodedPv);
RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) kf.generatePrivate(keySpecPv);
提示是使用
RSAPrivateCrtKey
类,该类公开方法
rsaPrivateKey.getPublicExponent()
之后我们可以打电话
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent());
return kf.generatePublic(publicKeySpec);
我通过计算文件签名来测试这个解决方案,并在每次生成新的公钥后验证它。
要测试一对,只需使用一个密钥加密某些内容并使用另一个密钥解密,看看是否能得到原始结果。