7

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?

jww
  • 90,984
  • 81
  • 374
  • 818
Aravind S
  • 443
  • 1
  • 8
  • 23
  • 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

2 Answers2

15

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);
Peter Walser
  • 14,278
  • 4
  • 52
  • 73
  • 1
    Thanks a lot, it worked! And I must research on this code too. – Aravind S Mar 22 '18 at 11:54
  • 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
  • Thanks for the explanation, will look into the link too. – Aravind S Mar 22 '18 at 15:14
3

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());
neubert
  • 14,976
  • 22
  • 102
  • 184