X509Certificate2.Export 相当于 java

X509Certificate2.Export equivalent in java

我正在尝试将一些现有代码从 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.

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

如何在这些 languages/frameworks 之间获得相同的结果?

  1. 我测试了两个代码片段(C# 和 Java),它们都有效并且 PFX/PKCS12 文件都有效,但内容可能不同(CA 链、密钥、包属性、供应商,……)。
  2. 要查看内容,您可以使用以下方法分析两个文件:
    openssl pkcs12 -info -in P12FILE.p12
    在输出中您可以看到不同之处。
  3. KeyStore.Store(…) 存储 container/bag 及其实例持有的所有内容(证书、CA 链、privKey)。
    X509Certificate2.Export(...) with X509ContentType.pfx returns 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());

如果您需要整个容器可能带有密钥和 CA 链:

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

如果您只需要一个证书,但 stored/wrapped 在 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

如果没有更多详细信息说明您正在尝试做什么、您有什么输入、预期输出是什么、限制是什么...很难给出更好和更少推测的答案。