在Java程序中,我想在Bouncy Castle的帮助下检索X509证书的指纹。

理想情况下,输出应与以下OpenSSL命令相同:

openssl x509 -noout -fingerprint -sha256 -inform pem -in <certificate-file>


我找到了一个可行的解决方案(请参阅下面的答案),但由于我使用的是Bouncy Castle测试包中的代码,因此感到很奇怪。

最佳答案

以下程序的输出与OpenSSL生成的指纹相同:18:C8:CF:46:B7:F4:3D:3B:F4:D8:15:A3:7E:ED:7C:6C:BC:FE:10:78:38:3D:F4:A0:42:EE:38:47:62:40:F7:2D

奇怪的是,方法fingerprint()sha256DigestOf()取自a Bouncy Castle test package。现在,我想知道是否有一个更“正式”的解决方案。

package fix.std.appl.signature;

import java.io.*;

import org.bouncycastle.cert.*;
import org.bouncycastle.crypto.digests.*;
import org.bouncycastle.util.encoders.*;
import org.bouncycastle.util.io.pem.*;

public class FingerPrintGen
{

  public static void main(String[] args) throws Exception
  {
    String cert = "-----BEGIN CERTIFICATE-----\r\n" +
        "MIIDvzCCAqegAwIBAgIUTs16QtKZeiGhKgeEyLFoNx5vglYwDQYJKoZIhvcNAQEL\r\n" +
        "BQAwbzELMAkGA1UEBhMCZm8xDDAKBgNVBAgMA2ZvbzEMMAoGA1UEBwwDZm9vMQww\r\n" +
        "CgYDVQQKDANmb28xDDAKBgNVBAsMA2ZvbzEMMAoGA1UEAwwDZm9vMRowGAYJKoZI\r\n" +
        "hvcNAQkBFgtmb29AYmFyLmNvbTAeFw0xOTExMjcxNDA5NDVaFw0yMDExMjYxNDA5\r\n" +
        "NDVaMG8xCzAJBgNVBAYTAmZvMQwwCgYDVQQIDANmb28xDDAKBgNVBAcMA2ZvbzEM\r\n" +
        "MAoGA1UECgwDZm9vMQwwCgYDVQQLDANmb28xDDAKBgNVBAMMA2ZvbzEaMBgGCSqG\r\n" +
        "SIb3DQEJARYLZm9vQGJhci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\r\n" +
        "AoIBAQC4/GxCml0Wv+sMbMx6uuL1qrTQauApboQbPexsJh26cFapqVMRBGfmGsGr\r\n" +
        "wo/Cngk3+rhrkzI51j6ZpeSmED5oQPFan8YV9qMAi/OY1oXKzVhEFlGnveF8yNBO\r\n" +
        "c81J/kyL8y0bmS1zSm7z9LA3vHvdZ1D7es6bv5/G5hrCDTqZSWJElfn84GtByQGn\r\n" +
        "H1DqSaRm9iusg8RmwHk0u5s7cTszapEgOjWZoCTJR8LjaT5mre2RYQlSNDtIaQpz\r\n" +
        "8RvMZ4S/HFCNSgWAbDA/Jj5KM6Uz603SVIraGN3m3r8ZlKZXxJbh48YoUmb1yb+D\r\n" +
        "zyFYt7KA66CUIph13vWG4SaoxIEjAgMBAAGjUzBRMB0GA1UdDgQWBBSEOoT+JZ+2\r\n" +
        "rA3QhnVyq0QjY7TeTjAfBgNVHSMEGDAWgBSEOoT+JZ+2rA3QhnVyq0QjY7TeTjAP\r\n" +
        "BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAyIT9A7LUgucrahIfy\r\n" +
        "1k/6Oq3cAHqCkc44DbnjMdhGJpS3EtpSaDzsWwz7yvALL/wG1iXtdAzHPWh+Iefl\r\n" +
        "WF148WBlEDn7jz6qMXVv0+pKasMjCb1axBDrUyvwSoA8kZTTLB3hcw0uxQ/yEeAb\r\n" +
        "6PC+0Qemw7vj071R/K+EIqB3JTnLXHtKx2N2gKVsEPsEiA3XP6QogvxRjKjYogCQ\r\n" +
        "1yI1fQrEXLHgCO/EejMd/7EgycEIpddPrRCFfFPXikCwZP48yY/FDtNOOXSF/key\r\n" +
        "T532czNtJtiXqTX6fpDeicgVXSlCb2Q4n3iUviEFSFLGwDMjx8Cd0/bL+RSPAB3d\r\n" +
        "F7Is\r\n" +
        "-----END CERTIFICATE-----\r\n" +
        "\r\n" ;

    String fp = getFingerprint(cert);
    System.out.println(fp);
  }

  public static String getFingerprint(String file) throws Exception
  {
    try (PemReader pemReader = new PemReader(new StringReader(file)))
    {
      PemObject pemObject = pemReader.readPemObject();
      X509CertificateHolder certHolder = new X509CertificateHolder(pemObject.getContent());
      return fingerprint(certHolder.toASN1Structure());
    }
  }

  /**
  * The following two methods are taken from a Bouncy castle test package.
  * https://github.com/bcgit/bc-java/blob/master/tls/src/test/java/org/bouncycastle/tls/test/TlsTestUtils.java
  */
  static String fingerprint(org.bouncycastle.asn1.x509.Certificate c)
      throws IOException
  {
    byte[] der = c.getEncoded();
    byte[] sha1 = sha256DigestOf(der);
    byte[] hexBytes = Hex.encode(sha1);
    String hex = new String(hexBytes, "ASCII").toUpperCase();

    StringBuffer fp = new StringBuffer();
    int i = 0;
    fp.append(hex.substring(i, i + 2));
    while ((i += 2) < hex.length())
    {
      fp.append(':');
      fp.append(hex.substring(i, i + 2));
    }
    return fp.toString();
  }

  static byte[] sha256DigestOf(byte[] input)
  {
    SHA256Digest d = new SHA256Digest();
    d.update(input, 0, input.length);
    byte[] result = new byte[d.getDigestSize()];
    d.doFinal(result, 0);
    return result;
  }

}



关于java - 获取X509证书的指纹,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59072318/

10-12 00:29