如何通过提供私钥获得RSA公钥?

问题描述 投票:0回答:6

我正在寻找一个 Java 函数,它将获取 RSA 私钥并返回正确的 RSA 公钥?

或者,是否有一个函数可以告诉我们 RSA 私钥/公钥是否有效?

java security cryptography rsa
6个回答
13
投票

如果您将私钥作为 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();   
} 

6
投票

我想不出您需要这个的任何充分理由。但这里是:

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.");
  }
}

1
投票

正如其他人所指出的,如果您有

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



0
投票
RSAPrivateKey

的对象,那么您需要做两件事:


获取模数。简单:
    privateKey.getModulus()
  1. 计算公共指数。这有点棘手,但并非不可能。请参阅
  2. 公共指数的定义
  3. 。通常,公共指数是 65537
    
    
    
  4. 得到模数和公共指数后,你可以按照PeteyB的回答来操作。


0
投票

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

我通过计算文件签名来测试这个解决方案,并在每次生成新的公钥后验证它。


-4
投票

要测试一对,只需使用一个密钥加密某些内容并使用另一个密钥解密,看看是否能得到原始结果。

© www.soinside.com 2019 - 2024. All rights reserved.