如何以编程方式从pkcs12文件导出公钥

时间:2015-02-19 18:45:56

标签: java bouncycastle public-key

我在尝试导出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()));
//...

谢谢!

1 个答案:

答案 0 :(得分:3)

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

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

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