Is there a way to validate in java if the given private key, say certain *.key file matches with the certain public key, to a certain .pub file using RSA algorithm?
-
You did not specify the algorithm used, but maybe this is helpful: https://stackoverflow.com/questions/4428236/given-two-ssh2-keys-how-do-i-check-that-they-belong-to-the-same-key-pair-in-java – Thilo Mar 22 '18 at 11:01
-
Its RSA algorithm, specified in the tags and updated the question. And thanks for the link. – Aravind S Mar 22 '18 at 11:11
3 Answers
You can verify if a key pair matches by
- creating a challenge (random byte sequence of sufficient length)
- signing the challenge with the private key
- verifying the signature using the public key
This gives you a sufficiently high confidence (almost certainity) that a key pair matches if the signature verification is ok, and an absolute certainity that a key pair does not match otherwise.
Example code:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// create a challenge
byte[] challenge = new byte[10000];
ThreadLocalRandom.current().nextBytes(challenge);
// sign using the private key
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(privateKey);
sig.update(challenge);
byte[] signature = sig.sign();
// verify signature using the public key
sig.initVerify(publicKey);
sig.update(challenge);
boolean keyPairMatches = sig.verify(signature);
This also works with Elliptic Curve (EC) key pairs, but you need to use a different signature algorithm (SHA256withECDSA
):
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(new ECGenParameterSpec("sect571k1"));
...
Signature sig = Signature.getInstance("SHA256withECDSA");

- 15,208
- 4
- 51
- 78
-
1
-
And can you provide any link related to this, so I can understand it's working? – Aravind S Mar 22 '18 at 12:37
-
Java tutorial: generating and verifying signatures -> https://docs.oracle.com/javase/tutorial/security/apisign/index.html – Peter Walser Mar 22 '18 at 13:40
-
Usually signatures are used to verify that a message was not altered. It can also be used to identify the parties (one owning the private key, the other owning the public key) by using a challenge that is signed and then verified. We use this for authentication: server poses a challenge, client signs it (with the private key) and the server validates the identity by verifying the signed challenge (with the client's public key). – Peter Walser Mar 22 '18 at 13:44
-
The answer that was marked as being correct wastes a lot of CPU cycles. This answer is waaaay more CPU efficient:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// comment this out to verify the behavior when the keys are different
//keyPair = keyGen.generateKeyPair();
//publicKey = (RSAPublicKey) keyPair.getPublic();
boolean keyPairMatches = privateKey.getModulus().equals(publicKey.getModulus()) &&
privateKey.getPublicExponent().equals(publicKey.getPublicExponent());
(the other answer signs a message with the private key and then verifies it with the public key whereas my answer checks to see if the modulus and public exponent are the same)

- 15,947
- 24
- 120
- 212
-
This answer does not work with general key pairs (EC, DSA, ...) but only with RSA key pairs. – Peter Walser Nov 07 '22 at 10:43
-
1@PeterWalser - that's true but the OP's question was "_using RSA algorithm_". But even then, you still don't need to sign / verify, even with EC or DSA. With EC you'd check to make sure that the curve is the same along with the QA parameter. Technically, I suppose a EC private key might not have QA available but I feel like most real world EC keys would just as most real world RSA private keys have the public exponent embedded within them. I mean, like with RSA, technically, all you need is the modulus and the private exponent but most real world RSA private keys include CRT components as well – neubert Nov 07 '22 at 13:25
boolean keyPairMatches = privateKey.getModulus().equals(publicKey.getModulus()) && privateKey.getPublicExponent().equals(publicKey.getPublicExponent());
java.security.interfaces.RSAPrivateKey
doesn't have getPublicExponent() method.
org.bouncycastle.asn1.pkcs.RSAPrivateKey
has getPublicExponent() method.
So,if you don't want to use bouncycastle
, you have to use the sign&verify
answer.

- 822
- 4
- 14
- 35

- 1
- 1