java.security.KeyStore 仅显示 p12 文件中两个证书之一

标签 java security export certificate keystore

好的,我通过执行以下操作导出了浏览器中的所有证书:工具、选项...、高级、加密、查看证书、您的证书、全部备份...(这是在 Firefox 中)。

证书列表中有 4 个证书,其中两个证书具有一个名称并具有不同的序列号,另外两个证书具有不同的名称并具有另外两个不同的序列号。所以,总的来说,有四个证书,其中两对具有相同的名称但不同的序列号。

如果我将此 p12 文件导入到另一台计算机上的另一个浏览器中,我将获得所有四个证书(如预期)。

--但是--

当我使用 java.security.* 包打开 p12 文件并查看 size() 时,它仅显示 p12 文件中的两个证书。当我循环浏览别名时,我只看到两个证书。 KeyStore 对象中是否有某些内容允许我访问所有四个证书?这很困难,因为两对的别名相同,只是序列号不同。预先感谢您提供的任何帮助。

最佳答案

好吧,回答我自己的古老问题...我了解到 Java 并不擅长读取 p12 文件。它使用每个证书的别名作为 key 创建一个 HashMap ,因此如果有两个具有相同别名的证书,Java 将用具有相同别名( key )的第二个证书破坏第一个证书,从而导致每个别名只有一个证书。

将证书导入浏览器时,浏览器会获取 p12 文件中的所有条目(不关心别名)。

我解决这个问题的方法是使用 Java 运行时执行功能来调用 openssl 并将每个证书的输出通过管道传输到字符串中,并使用该字符串创建 X509Certificate。这是一些示例代码(我无法复制和粘贴,因为我的开发盒未连接互联网):

private ArrayList<X509Certificate> parseCerts( String fileName, String pwd ) {
   ArrayList certsFromP12File = new ArrayList();
   String cmdLine = "/usr/bin/openssl pkcs12 -info -in " + fileName + " -clcerts -nokeys -passin pass:" + pwd;

   String line;

   Process p = Runtime.getRuntime().exec( cmdLine );

   BufferedReader input = new BufferedReader( new InputStreamReader( p.getInputStream() ) );

   boolean readingCert = false;
   boolean gotCertToProcess = false;
   String certString;

   while ((line=input.readLine()) != null ) {
      if ( line.contains("-----BEGIN CERTIFICATE-----") ) {
         readingCert = true;
      }
      if ( readingCert ) {
         certString += line + System.getProperty("line.separator");
      }
      if ( line.contains("-----END CERTIFICATE-----") ) {
         readingCert = false;
         getCertToProcess = true;
      }
      if ( gotCertToProcess ) {
         X509Certificate cert = null;
         byte[] cert_bytes = certString.getBytes();
         ByteArrayInputStream certInputStream = new ByteArrayInputStream(cert_bytes);
         cert = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate( certInputStream );
         certsFromP12File.add( cert );
         gotCertToProcess = false;
         certString = "";
      }
   }
   input.close();

   return certsfromP12File;
}

希望对其他人有帮助。 :)

关于java.security.KeyStore 仅显示 p12 文件中两个证书之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5554085/

相关文章:

vb.net - 编译或导出编码表单

java - 通过java客户端查询主键 - Aerospike

java - root 用户可以在运行的 JVM 中访问哪些信息?

php security 我应该在 url 中隐藏查询字符串吗

java - XXE billion laughs 攻击似乎没有像 Sonar 推荐的防止 XXE 攻击的解决方案预期的那样得到缓解

MySQL 导出单列仅显示一次重复条目

java - 在 Java 中报告 Web 服务调用进度

java - 使用 apache-commons-cli 排除 HelpFormatter.printHelp() 中的几个选项

java - Spring security - authorizerequest()、anyRequest() 和authenticated() 有什么作用?

javascript - 为 vuejs 项目导入/导出 javascript 变量