java - Java 中的 X509Certificate2.Export 等效项

标签 java x509certificate

我正在尝试将一些现有代码从 C# 移植到 Java,此特定部分使用 X509Certificate2.Export方法获取导出为 byte[] 的证书,以便稍后编码为 Base64。

var pfxPassword = "passw0rd";
var appCert = new X509Certificate2("c:\\mycert.pfx", pfxPassword, X509KeyStorageFlags.Exportable);
byte[] certificateBytes = certificate.Export(X509ContentType.Pfx, pfxPassword);
string certString = Convert.ToBase64String(certificateBytes);
System.Console.WriteLine(certString);

所以我尝试使用 KeyStore.store() java方法

String caPassword = "passw0rd";
KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(new FileInputStream(new File("c:\\mycert.pfx")), caPassword.toCharArray());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
keyStore.store(outputStream, caPassword.toCharArray());
byte[] encodedBytes = Base64.encodeBase64(outputStream.toByteArray());
String result = new String(encodedBytes, "UTF-8");
System.out.println(result);

根据导出和存储的文档:

Export: Exports the current X509Certificate object to a byte array in a format described by one of the X509ContentType values, and using the specified password.

store: Stores this keystore to the given output stream, and protects its integrity with the given password.

但是使用相同的输入文件和密码短语,这些代码片段在大小和内容上给了我不同的结果,那么为什么会发生这种情况呢?

如何在这些语言/框架之间获得相同的结果?

最佳答案

  1. 我测试了两个代码片段(C# 和 Java),它们都可以工作,并且 PFX/PKCS12 文件都有效,但内容可能不同(CA 链、 key 、包属性、提供商等)。
  2. 要查看内容,您可以使用以下命令分析这两个文件:
    openssl pkcs12 -info -in P12FILE.p12
    在输出中您可以看到不同之处。<
  3. KeyStore.Store (...) 存储容器/包及其实例所拥有的所有内容(证书、CA 链、私钥)。
    X509Certificate2.Export (...) 与 X509ContentType.pfx返回 PFX 格式的证书(仅一个证书)。和:

    The Pkcs12 value is identical to the Pfx value.

如果您只需要 X509 证书,那么这就足够了:

String caPassword = "passw0rd";
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream( new File(“PKCS12Path") ), caPassword.toCharArray());
X509Certificate cert = (X509Certificate)ks.getCertificate(sAlias);
String yourB64Certificate = encoder.encodeBuffer(cert.getEncoded());

如果您需要整个容器以及可能的 key 和 CA 链:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ks.store(outputStream, caPassword.toCharArray());
String result = new BASE64Encoder().encode(outputStream.toByteArray());

如果您只需要一个证书,但存储/包装在 PKCS12 容器中(如 C# 中):

KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null,null); //empty container
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ks.setCertificateEntry("alias", x509Cert);
String result = new BASE64Encoder().encode(outputStream.toByteArray()); //for your base64 string

如果没有更多关于您想要做什么、您有什么输入、预期输出是什么、限制是什么......的详细信息,很难给出更好、更少猜测的答案。

关于java - Java 中的 X509Certificate2.Export 等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37059355/

相关文章:

java - volatile 是否给其他正常存储并加载发生之前的关系?

silverlight - 是否可以将客户端证书与来自 Windows Phone 7 的 HTTPS 请求一起使用?

wcf - 您可以使用 SoapUI 测试受证书保护的 WCF 服务吗?

wcf - 运行 fiddler 时得到 "Could not establish trust relationship for the SSL/TLS secure channel with authority"

java - 如何在没有 Eclipse 的情况下在 Java 中导入类?

java - AntlrWorks 2.1 - 不弹出解析树 (GUI)

java - android studio更新到3.0.1版本后报错

c# - 无法验证在 C# 中创建的签名

c# - C#中如何判断哪个个人证书来自硬件设备?

Java 符号 (&) 正则表达式