(Java) 在 Mac OS X 上以编程方式访问“系统根目录”下的 SSL 证书

2024-05-09

我正在编写一个 Java 应用程序,它可以通过远程 Https 站点进行 REST Api 调用。远程站点由受信任的证书签名。它在 Windows 上运行良好,但由于 SSL 证书问题,在 OS X 上运行时遇到问题。

我做了一些挖掘,发现原因与我如何使用 getInstance 调用在代码中初始化 KeyStore 对象有关。它仅从“系统”钥匙串读取证书,而不是从“系统根”钥匙串读取证书。下面是从密钥库打印出所有证书的代码片段。

// In windows use "WINDOWS-ROOT"
KeyStore osTrustManager = KeyStore.getInstance("KeychainStore");
osTrustManager.load(null, null);

Enumeration<String> enumerator = osTrustManager.aliases();
while (enumerator.hasMoreElements()) {
    String alias = enumerator.nextElement();
    if (osTrustManager.isCertificateEntry(alias)) {
        m_logger.info(String.format("%s (certificate)\n", alias));
    }
}

如何更改代码才能实现这一目标?如果有人能插话,我们将不胜感激。

这是“系统根”下的证书示例OS X 的屏幕截图 https://i.stack.imgur.com/ou2Na.png


我不知道是否有某种KeyStore它允许您访问 Mac OS X 系统根证书,但您可以尝试其他方式。

在 Mac OS X 中,您可以使用以下命令从任何钥匙串获取证书列表security命令。

例如,此命令将为您提供有关系统根钥匙串中安装的不同证书的信息:

security find-certificate -a "/System/Library/Keychains/SystemRootCertificates.keychain"

该实用程序有两个标志,-p,这会将每个证书输出为 PEM 编码,并且-a,这允许我们按名称过滤结果 - 由于系统中安装了大量 CA,这很方便。

这个想法是使用 Java 中的这个实用程序。

不久前,我偶然发现了一个名为客户公司 https://github.com/ctt-gob-es/clienteafirma旨在处理数字签名。

这个库有一个类叫做苹果脚本 https://github.com/ctt-gob-es/clienteafirma/blob/d7b211e2ce50bbd9cdbda20e95746122f8fac783/afirma-keystores-mozilla/src/main/java/es/gob/afirma/keystores/mozilla/apple/AppleScript.java。这个类基本上是一个包装器Process这允许我们运行任意命令。

以下代码使用该类和security命令获取所有颁发的证书,例如,VeriSign:

public static void main(String... args) {
  // Keychains that we can use
  final String KEYCHAIN_PATH = "/Library/Keychains/System.keychain";
  final String SYSTEM_KEYCHAIN_PATH = "/System/Library/Keychains/SystemRootCertificates.keychain";
  // Show me only certificates from VeriSign
  final String AUTHORITY = "VeriSign";
  final String OSX_SEC_COMMAND = "security find-certificate -a -p -c %AUTHORITY% %KEYCHAIN%";
  final String cmd = OSX_SEC_COMMAND.replace("%AUTHORITY%", AUTHORITY).replace("%KEYCHAIN%", SYSTEM_KEYCHAIN_PATH);
  System.out.println(cmd);
  System.out.println();

  final AppleScript script = new AppleScript(cmd);
  InputStream certificateStream = null;
  try {
    // Run script
    final String result = script.run();
    certificateStream = new ByteArrayInputStream(result.getBytes());
    // Process the output of the command
    final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    final Collection<X509Certificate> certificates = (Collection<X509Certificate>) certificateFactory.generateCertificates(certificateStream);
    // Use the certificates as you need
    for (X509Certificate certificate : certificates) {
      String alias = certificate.getSubjectX500Principal().getName();
      System.out.println("Certificate: " + alias);
    }
  } catch (Throwable t) {
    t.printStackTrace();
  } finally {
    if (certificateStream != null) {
      try {
        certificateStream.close();
      } catch (IOException io) {
        io.printStackTrace();
      }
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(Java) 在 Mac OS X 上以编程方式访问“系统根目录”下的 SSL 证书 的相关文章

随机推荐