0

我正在尝试为 Web 服务的 Java 客户端添加证书支持。java 客户端负责收集所需的信息并将格式化的信息传递给进行 http\https 调用的 c++ 库。我们目前正在使用 JNI 来调用 c++ 库。c++ 库需要一个 PCCERT_CONTEXT 参数作为证书传递。

我阅读了 Java 中的证书并获得了它的编码版本,如下所示:

KeyStore keystore = KeyStore.getInstance("pkcs12", "SunJSSE");
InputStream is = this.getClass().getResourceAsStream(certificateName);
keystore.load(is, password);

Certificate[] chain = keystore.getCertificateChain(alias);
X509Certificate x509Certificate = (X509Certificate) chain[0];

byte[] encodedCertificate = x509Certificate.getEncoded();

我将此编码证书传递给 JNI 层,在 JNI 中我执行以下操作来构造 PCCERT_CONTEXT:

PCCERT_CONTEXT certContext = NULL;
std::vector<BYTE> certData;
if (clientCertificateSize > 0)
{
    jbyte* dataElements = env->GetByteArrayElements(encodedCertificate, 0);
    for (int i = 0; i < clientCertificateSize; i++) {
        certData.push_back(dataElements[i]);
    }

    certContext = CertCreateCertificateContext(
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        certData.data(),
        (DWORD)clientCertificateSize);

}

当我将此 certContext 传递给 c++ 库(内部使用 winHttp)时,我收到错误 ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY (12185),这表明 PCCERT_CONTEXT 没有设置私钥。

我可以按如下方式在 Java 中获取编码的私钥:

KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
                new KeyStore.PasswordProtection(password));
PrivateKey privateKey = pkEntry.getPrivateKey();
        
byte[]  encodedPrivateKey = privateKey.getEncoded();

并将 encodedPrivateKey 传递给 JNI 层,但是如何使用这个 enodedPrivateKey 在 PCCERT_CONTEXT 对象中设置私钥?

有没有办法用私钥创建 PCCERT_CONTEXT ?有一个更好的方法吗 ?我是证书新手,所以任何建议都会有所帮助。

谢谢

4

0 回答 0