繁体   English   中英

从私钥模数和私钥指数中获取 RSA 公钥

[英]Get RSA public key from private key modulus and private exponent

我一直在阅读一些 RSA 文献和堆栈溢出问题,但没有得到明确的答案。

仅给定 RSA 私钥模数和私有指数,这就是我所拥有的(也足以用于所有与加密相关的操作),我可以获得相关的公钥模数和公共指数吗?

另外,我可以仅使用这两个参数获取私钥的编码形式吗? 我在 java 中尝试了以下操作(java 不是实际的要求),但是支持它的 OpenSSL 引擎失败并显示错误:04000090:RSA 例程:OPENSSL_internal:VALUE_MISSING

@NonNull
public static byte[] getEncodedRsaPrivateKey(@NonNull BigInteger nModulus, @NonNull BigInteger nPrivateExponent) throws NoSuchAlgorithmException, InvalidKeySpecException {
    RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(nModulus, nPrivateExponent);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
    return privateKey.getEncoded();
}

我想这两个问题的答案都是否定的,但我不确定。

通常RSA私钥包含以下数据:

  • n - 半素模数

  • d - 私有指数

  • p & q - n质因数

  • e - 公共指数

至少,私钥必须包含:

  • nd

所以回答你的问题:

我可以得到相关的公钥模数吗?

是的,你已经拥有了。 它与私钥使用的n相同。

我可以得到公共指数吗?

不知道pq并不容易,尽管您可以猜测它,但它几乎总是一个小素数,最常见的是365537

尝试两者并检查密文是否有效。

按照@Woodstock 的指示,我搜索了公共指数并成功了:

int nPublicExponent;
boolean bFound = false;
for (nPublicExponent = 3; nPublicExponent <= 65537; nPublicExponent++) {
    publicKeySpec = new RSAPublicKeySpec(privateKey.getModulus(), new BigInteger(String.valueOf(nPublicExponent)));
    publicKey = rsaKeyFactory.generatePublic(publicKeySpec);
    if (publicKey == null) {
        continue;
    }
    byte[] encryptMessage = testEncrypt("hello", publicKey);
    if (encryptMessage == null) {
        continue;
    }
    String sMessage = testDecrypt(encryptMessage, privateKey);
    if (TextUtils.isEmpty(sMessage)) {
        continue;
    }
    if (TextUtils.equals(sMessage, "hello")) {
        bFound = true;
        break;
    }
}
if (!bFound) {
    Utils.DebugLog("Public exponent not found");
} else {
    Utils.DebugLog("Public exponent found: " + nPublicExponent);
}

@Nullable
public static byte[] testEncrypt(String sMessage, PublicKey publicKey) {
    try {
        Cipher encrypt =  Cipher.getInstance("RSA/ECB/PKCS1Padding");
        encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
        return encrypt.doFinal(sMessage.getBytes());
    } catch (Exception ex) {
        return null;
    }
}

@Nullable
public static String testDecrypt(byte[] encryptedMessage, Key privateKey) {
    try {
        Cipher decrypt = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        decrypt.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(decrypt.doFinal(encryptedMessage));
    } catch (Exception ex) {
        return null;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM