如何验证私钥与证书是否匹配?

sur*_*r_s 5 java ssl cryptography bouncycastle

我将私钥存储为 .key 文件。

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQD5YBS6V3APdgqaWAkijIUHRK4KQ6eChSaRWaw9L/4u8o3T1s8J
rUFHQhcIo5LPaQ4BrIuzHS8yzZf0m3viCTdZAiDn1ZjC2koquJ53rfDzqYxZFrId
7a4QYUCvM0gqx5nQ+lw1KoY/CDAoZN+sO7IJ4WkMg5XbgTWlSLBeBg0gMwIDAQAB
AoGASKDKCKdUlLwtRFxldLF2QPKouYaQr7u1ytlSB5QFtIih89N5Avl5rJY7/SEe
rdeL48LsAON8DpDAM9Zg0ykZ+/gsYI/C8b5Ch3QVgU9m50j9q8pVT04EOCYmsFi0
DBnwNBRLDESvm1p6NqKEc7zO9zjABgBvwL+loEVa1JFcp5ECQQD9/sekGTzzvKa5
SSVQOZmbwttPBjD44KRKi6LC7rQahM1PDqmCwPFgMVpRZL6dViBzYyWeWxN08Fuv
p+sIwwLrAkEA+1f3VnSgIduzF9McMfZoNIkkZongcDAzjQ8sIHXwwTklkZcCqn69
qTVPmhyEDA/dJeAK3GhalcSqOFRFEC812QJAXStgQCmh2iaRYdYbAdqfJivMFqjG
vgRpP48JHUhCeJfOV/mg5H2yDP8Nil3SLhSxwqHT4sq10Gd6umx2IrimEQJAFNA1
ACjKNeOOkhN+SzjfajJNHFyghEnJiw3NlqaNmEKWNNcvdlTmecObYuSnnqQVqRRD
cfsGPU661c1MpslyCQJBAPqN0VXRMwfU29a3Ve0TF4Aiu1iq88aIPHsT3GKVURpO
XNatMFINBW8ywN5euu8oYaeeKdrVSMW415a5+XEzEBY=
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)

我从 ssl 证书文件中提取了公钥。

下面是我尝试验证私钥是否与 ssl 证书匹配的代码。

我使用模数[即私钥获取模数==公钥获取模数]来检查它们是否匹配。

这似乎只适用于 RSAKEYS..

但我也想检查其他钥匙..

还有其他替代方法可以做同样的事情吗??

  private static boolean verifySignature(File serverCertificateFile, File serverCertificateKey) {
    try {
        byte[] certificateBytes = FileUtils.readFileToByteArray(serverCertificateFile);
        //byte[] keyBytes = FileUtils.readFileToByteArray(serverCertificateKey);
        RandomAccessFile raf = new RandomAccessFile(serverCertificateKey, "r");
        byte[] buf = new byte[(int) raf.length()];
        raf.readFully(buf);
        raf.close();
        PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
        KeyFactory kf;
        try {
            kf = KeyFactory.getInstance("RSA");

            RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(kspec);


            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            InputStream in = new ByteArrayInputStream(certificateBytes);
            //Generate Certificate in X509 Format
            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in);
            RSAPublicKey publicKey = (RSAPublicKey) cert.getPublicKey();

            in.close();
            return privKey.getModulus() == publicKey.getModulus();

        } catch (NoSuchAlgorithmException ex) {
            logger.log(Level.SEVERE, "Such algorithm is not found", ex);
        }  catch (CertificateException ex) {
            logger.log(Level.SEVERE, "certificate exception", ex);
        } catch (InvalidKeySpecException ex) {
            Logger.getLogger(CertificateConversion.class.getName()).log(Level.SEVERE, null, ex);
        }

    } catch (IOException ex) {
        logger.log(Level.SEVERE, "Signature verification failed.. This could be because the file is in use", ex);
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

而且代码也不起作用..抛出 invalidkeyspec 异常

Ant*_*nov 2

那么,成对参数检查有什么问题呢?

\n\n
    \n
  • 如果证书指定类型为 \xe2\x80\x9cRSA\xe2\x80\x9d 的公钥,则:\n
      \n
    1. 从密钥文件中提取n, 。e
    2. \n
    3. 将这些值与证书中的值进行比较。
    4. \n
  • \n
  • 如果证书指定类型为 \xe2\x80\x9cDSA\xe2\x80\x9d 的公钥,则:\n
      \n
    1. 从密钥文件中提取p, q, g, 。y
    2. \n
    3. 将这些值与证书中的值进行比较。
    4. \n
  • \n
  • 如果证书指定类型为 \xe2\x80\x9cblah-blah\xe2\x80\x9d 的公钥,则:\n
      \n
    1. 从密钥文件中提取相应的值。
    2. \n
    3. 将这些值与证书中的值进行比较。
    4. \n
  • \n
\n\n

依此类推,即每种算法都需要其自己的正确处理。如果密钥文件格式实际上是自定义的,则可能不存在通用算法。但是,您仍然可以通过仅指定值索引来稍微概括它:

\n\n
ComparisonScheme = new Dictionary<String, Integer[2][]> {\n    { "RSA", {{0, 0}, {1, 1}} },\n    { "DSA", {{0, 1}, {1, 2}, {2, 3}, {3, 0}} },\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这只是一个说明,当然,\xe2\x80\x94 不要认真对待语法和数字。

\n