如何从Android项目的RSA代码中获取c、d、p、q参数?
Hey there! Let's break down how to grab those RSA parameters you need—first, a quick clarification: RSA's core key parameters are the prime factors p and q, private exponent d, public exponent e, and modulus n = pq*. If you mentioned "c" referring to the encrypted ciphertext, that's a result of encrypting data with the public key, not a key parameter. I'll cover both scenarios below!
Step 1: Cast Keys to RSA-Specific Types
The PublicKey and PrivateKey objects from your code are abstract—you need to cast them to their concrete RSA implementations to access the underlying parameters. The private key generated by KeyPairGenerator is actually an RSAPrivateCrtKey (which includes CRT parameters like p and q), while the public key is an RSAPublicKey.
Step 2: Add Methods to Extract Parameters
Here's how to modify your existing RSA class to fetch p, q, d, e, n, and generate ciphertext (c):
import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import javax.crypto.Cipher; import java.math.BigInteger; public class RSA { private final static String RSA = "RSA"; public static PublicKey puk; public static PrivateKey prk; public static void generateKey() throws Exception { KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); gen.initialize(512, new SecureRandom()); KeyPair keyPair = gen.generateKeyPair(); puk = keyPair.getPublic(); prk = keyPair.getPrivate(); } // Extract and print core RSA key parameters public static void extractKeyParams() { // Get public key params (n, e) if (puk instanceof RSAPublicKey rsaPub) { BigInteger modulus = rsaPub.getModulus(); BigInteger publicExponent = rsaPub.getPublicExponent(); System.out.println("Modulus (n): " + modulus); System.out.println("Public exponent (e): " + publicExponent); } // Get private key params (p, q, d) if (prk instanceof RSAPrivateCrtKey rsaPrivCrt) { BigInteger primeP = rsaPrivCrt.getPrimeP(); BigInteger primeQ = rsaPrivCrt.getPrimeQ(); BigInteger privateExponent = rsaPrivCrt.getPrivateExponent(); System.out.println("Prime factor p: " + primeP); System.out.println("Prime factor q: " + primeQ); System.out.println("Private exponent d: " + privateExponent); } } // Generate ciphertext (c) by encrypting plaintext public static byte[] getCiphertext(byte[] plaintext) throws Exception { Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.ENCRYPT_MODE, puk); return cipher.doFinal(plaintext); } public static void main(String[] args) throws Exception { generateKey(); extractKeyParams(); // Example: Generate ciphertext for a sample plaintext String plaintext = "Hello RSA!"; byte[] ciphertext = getCiphertext(plaintext.getBytes()); System.out.println("Ciphertext (c): " + new BigInteger(1, ciphertext).toString(16)); // Print as hex } }
Key Notes:
- Why
RSAPrivateCrtKey? This subclass ofRSAPrivateKeyexposes getters for the prime factors p and q, which the basicRSAPrivateKeyinterface does not. SinceKeyPairGeneratorgenerates CRT-formatted private keys by default, this cast will work. - Ciphertext (c): As mentioned, this isn't a key parameter—it's the output of encrypting data with the public key. The example above converts it to a hex string for readability.
- 512-bit keys: Note that 512-bit RSA is no longer considered secure for production use. For real-world applications, use at least 2048 bits (or 4096 for higher security).
内容的提问来源于stack exchange,提问作者Joe

