java - 获取X509证书的指纹

标签 java bouncycastle

在 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/

相关文章:

java - 在 Java 中通过 Web 服务下载大文件

java - 使用Index API同步将数千条记录索引到Elasticsearch中是正确的方法吗?

java - 如何在 Java 中生成多域 (UCC) 证书?

java - 使用 bouncycaSTLe 对集中式 PKI 中的私钥进行加密

java - 无法打开生成的 zip 文件

java - JFrame 关闭操作

java - 从Java代码获取队列HornetQ列表

c# - 如何从 AES-GCM 获取认证标签

java - gpg --list-keys 为空但文件解密 bouncycaSTLe 加密文件

java - BouncycaSTLe DER长度IO错误: