如何通过提供 PrivateKey 来获得 RSA PublicKey?
Posted
技术标签:
【中文标题】如何通过提供 PrivateKey 来获得 RSA PublicKey?【英文标题】:How to get a RSA PublicKey by giving a PrivateKey? 【发布时间】:2012-07-05 22:01:12 【问题描述】:我正在寻找可以获取 RSA PrivateKey 并返回正确 RSA PublicKey 的 Java 函数?
或者,是否有一个函数可以告诉我们 RSA PrivateKey/PublicKey 是否有效?
【问题讨论】:
保持冷静。论坛与实时聊天完全不同。请始终牢记,用户在这里是自愿的,并且可以随时随地进行。 定义“有效”的含义。 除了给出的答案之外,如果您始终可以执行签名/验证(对任何值)以查看键是否匹配。请注意,有时这很麻烦,例如如果为私钥保留使用计数(某些 HSM 和智能卡会这样做)。仅比较模数或模数上的散列也很好,每个密钥对的模数应该是唯一的。不需要公共指数。 【参考方案1】:AFAIK 给定一个密钥,您无法派生 RSA 密钥对的另一个密钥。这相当于破坏了 RSA。
为了测试一对,只需使用一个密钥加密某些内容并使用另一个密钥解密,看看您是否能得到原始结果。
【讨论】:
非常感谢!你能对第二个答案更清楚一点吗?你有实际的 Java 代码吗? 我认为这是错误的。根据***.com/questions/5244129/…,您可以从私钥中获取公钥。 MK,你知道用Java怎么做吗? @MK 那是因为公钥包含在私钥中。 从私钥派生公钥当然是可能的。看我的回答。【参考方案2】:如果您将私钥作为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();
【讨论】:
构造函数其实是 RSAPublicKeySpec(BigIntegermodal,BigInteger publicExponent)docs.oracle.com/javase/7/docs/api/java/security/spec/…【参考方案3】:我想不出你需要这个的任何充分理由。但这里是:
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.");
【讨论】:
【参考方案4】:如果你有一个RSAPrivateKey
类型的对象,那么你需要做两件事:
-
获取模数。简单:
privateKey.getModulus()
计算公共指数。这有点棘手,但并非不可能。请参阅definition of public exponent。通常,公共指数是65537
。
得到模数和公共指数后,你可以按照 PeteyB 的回答。
【讨论】:
【参考方案5】:正如其他人所指出的,如果您有 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 );
【讨论】:
以上是关于如何通过提供 PrivateKey 来获得 RSA PublicKey?的主要内容,如果未能解决你的问题,请参考以下文章