我在尝试导出 pkcs12 文件中包含的公钥时遇到问题。我想要达到的结果与使用此命令(但以编程方式)相同:

keytool -export -alias mycertalias -keystore mykeystore.jks -rfc -file mypublickey.pem

我获得了公钥并使用 BouncyCaSTLe 生成了一个字符串,但是获得的结果与我使用上述命令获得的结果不匹配。这是我的代码:
KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(new FileInputStream(certPath),certPassword.toCharArray());
String alias = "mycertalias";
Certificate cert = keyStore.getCertificate(alias);

PublicKey publicKey = cert.getPublicKey();
StringWriter writer = new StringWriter();
PemWriter pemWriter = new PemWriter(writer);
pemWriter.writeObject(new PemObject("CERTIFICATE", publicKey.getEncoded()));
pemWriter.flush();
pemWriter.close();

System.out.println(writer.toString());

我曾尝试不使用 BouncyCaSTLe 并直接对字符串进行编码,但得到的结果与以前相同(因此它与使用 keytool 命令获得的结果都不匹配):
Certificate cert = keyStore.getCertificate(alias);
BASE64Encoder encoder = new BASE64Encoder();
PublicKey publicKey = cert.getPublicKey();
System.out.println(new String(encoder.encode(publicKey.getEncoded())));

知道我做错了什么吗?我在这里先向您的帮助表示感谢。

更新:

正如@dave_thompson_085 所建议的,我真正想要的是以 PEM 格式导出整个证书,所以有效的代码是这样的:
//...
Certificate cert = keyStore.getCertificate(alias);
StringWriter writer = new StringWriter();
PemWriter pemWriter = new PemWriter(writer);
pemWriter.writeObject(new PemObject("CERTIFICATE", cert.getEncoded()));
//...

谢谢!

最佳答案

您的 keytool 示例执行 JKS 而不是 P12,但添加 -storetype pkcs12 会执行 P12,所以我假设这就是您的意思。更重要的是,keytool -exportcert(在大约 1.5 中正式取代 -export)导出 整个证书,而不仅仅是公钥。 指定 -rfc 以 PEM 格式执行,省略 -rfc 以 DER 格式执行,但无论哪种方式,它都是整个证书。

此外,您的第二个代码不应产生相同的结果;它应该产生,也许是模换行符,与 PEM 格式的正文相同,但没有虚线 BEGIN 和 END 行。 BEGIN 和 END 行是 PEM 格式的一部分,没有它们就不是 PEM。并且没有说明正确的内容类型(您没有说明),这不是正确的 PEM。

如果您真的只想要公钥,您可以这样做,但不要期望它与证书相同,因为公钥不是证书。请注意,很少有应用程序可以单独使用公钥而无需证书中的其他数据;唯一想到的是 SSH(据说它会手动确认身份和有效性),OpenSSH 不使用 Java JCE 支持的基于 ASN1 的“X509”(实际上是 SPKI)编码,而是使用它自己的基于 base64-MPI 的编码编码。

关于java - 如何以编程方式从 pkcs12 文件导出公钥,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28614452/

10-13 09:11