我在尝试导出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()));
//...
谢谢!
答案 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的编码编码