如何在 Java 中验证 public 和私钥对

How to validate a public and private key pair in Java

有没有办法在 java 中验证给定的私钥,比如某个 *.key 文件与某个 public 密钥匹配,使用 RSA 算法到某个 .pub 文件?

您可以通过

验证密钥对是否匹配
  • 创建一个挑战(足够长度的随机字节序列)
  • 使用私钥
  • 签署挑战
  • 使用public密钥
  • 验证签名

这为您提供了足够高的置信度(几乎确定性),如果签名验证正常,则密钥对匹配,否则绝对确定密钥对不匹配。

示例代码:

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);

被标记为正确的答案浪费了很多 CPU 周期。这个答案更 CPU 有效:

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());