简体   繁体   English

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

[英]How to export public key from pkcs12 file programmatically

I am having trouble trying to export a public key contained in a pkcs12 file. 我在尝试导出pkcs12文件中包含的公钥时遇到问题。 What I am trying to achieve is the same result than with this command (but programmatically): 我想要实现的是与此命令相同的结果(但是以编程方式):

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

I obtain the public key and generate a string with BouncyCastle, but the obtained result doesn't match what I obtain with the command above. 我获取公钥并使用BouncyCastle生成一个字符串,但获得的结果与我在上面的命令中获得的结果不匹配。 Here is my code: 这是我的代码:

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());

I have tried not using BouncyCastle and directly encoding the string, but I get the same result than before (so it doesn't match either with the result obtained with the keytool command): 我曾尝试不使用BouncyCastle并直接编码字符串,但我得到的结果与之前相同(因此它与使用keytool命令获得的结果不匹配):

Certificate cert = keyStore.getCertificate(alias);
BASE64Encoder encoder = new BASE64Encoder();
PublicKey publicKey = cert.getPublicKey();
System.out.println(new String(encoder.encode(publicKey.getEncoded())));

Any idea of what am I doing wrong? 我知道我做错了什么吗? Thanks for the help in advance. 我在这里先向您的帮助表示感谢。

UPDATE: 更新:

As suggested by @dave_thompson_085 what I actually want is to export the whole certificate in PEM format, so the valid code is like this: 正如@ 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()));
//...

Thanks! 谢谢!

Your keytool example does a JKS not a P12, but adding -storetype pkcs12 would do P12 so I'll assume that's what you meant. 您的keytool示例执行JKS而不是P12,但添加-storetype pkcs12会执行P12,因此我假设这就是您的意思。 More importantly, keytool -exportcert (which officially superseded -export in about 1.5) exports the whole certificate, not just the public key. 更重要的是, keytool -exportcert (从而正式取代-export约1.5)出口的整个证书,而不仅仅是公共密钥。 Specifying -rfc does it in PEM format, and omitting -rfc does it in DER format, but either way it's the whole certificate. 指定-rfc以PEM格式进行,省略-rfc以DER格式进行,但无论哪种方式都是整个证书。

Also your second code should not produce the same result; 你的第二个代码也不应该产生相同的结果; it should produce, perhaps modulo line breaks, the same as the body of the PEM format, but without the dashed BEGIN and END lines. 它应该产生,也许是模数换行符,与PEM格式的主体相同,但没有虚线BEGIN和END行。 The BEGIN and END lines are part of the PEM format, and without them it's not PEM. BEGIN和END行是PEM格式的一部分,没有它们就不是PEM。 And without stating the correct type of the contents, which you don't, it's not correct PEM. 并且没有说明你没有的正确类型的内容,这是不正确的PEM。

If you really want just the publickey you can do that, but don't expect it to be the same as the certificate because a publickey is not a certificate. 如果您真的只想要公钥,那么您可以这样做,但不要指望它与证书相同,因为公钥不是证书。 Note that there there are very few applications that can use a publickey by itself without the other data in the certificate; 请注意,很少有应用程序可以单独使用公钥,而不需要证书中的其他数据; the only one that springs to mind is SSH (which supposedly confirms the identity and validity manually), and OpenSSH does not use the ASN1-based "X509" (really SPKI) encoding supported by Java JCE but instead its own base64-MPI-based encoding. 该弹簧想到的只有一个SSH(据称手动确认身份和有效性)和OpenSSH不会使用基于ASN1-“X509”(真SPKI)编码在Java JCE的支持,而是自己的-MPI为基础的base64编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM