问题
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?
回答1:
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);
回答2:
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());
来源:https://stackoverflow.com/questions/49426844/how-to-validate-a-public-and-private-key-pair-in-java