在开发Java web服务客户端期间,我遇到了一个问题。web服务的身份验证使用客户端证书、用户名和密码。我从webservice背后的公司收到的客户端证书是.cer格式的。当我使用文本编辑器检查文件时,它有以下内容:

-----BEGIN CERTIFICATE-----
[Some base64 encoded data]
-----END CERTIFICATE-----

我可以在Internet Explorer中导入该文件作为证书(无需输入密码!),并使用它进行webservice的身份验证。

I was able to import this certificate into a keystore by first stripping the first and last line, converting to unix newlines and running a base64-decode. The resulting file can be imported into a keystore (using the keytool command). When I list the entries in the keystore, this entry is of the type trustedCertEntry. Because of this entry type (?) I cannot use this certificate to authenticate with the webservice. I'm beginning to think that the provided certificate is a public certificate which is being used for authentication...

我发现的一个解决办法是在IE中导入证书,并将其导出为.pfx文件。该文件可以作为密钥存储库加载,并可用于使用webservice进行身份验证。但是,我不能期望我的客户每次收到新证书时都执行这些步骤。因此,我想将.cer文件直接加载到Java中。任何想法吗?

附加信息:webservice背后的公司告诉我,应该向稍后将导入证书的PC和用户请求证书(使用IE和网站)。


当前回答

下面是我一直用于以编程方式将.cer文件导入到新的KeyStore中的代码。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
//VERY IMPORTANT.  SOME OF THESE EXIST IN MORE THAN ONE PACKAGE!
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

//Put everything after here in your function.
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);//Make an empty store
InputStream fis = /* insert your file path here */;
BufferedInputStream bis = new BufferedInputStream(fis);

CertificateFactory cf = CertificateFactory.getInstance("X.509");

while (bis.available() > 0) {
    Certificate cert = cf.generateCertificate(bis);
    trustStore.setCertificateEntry("fiddler"+bis.available(), cert);
}

其他回答

这是我的工作方式:

在文本编辑器中按以下格式将证书数据保存为。txt ——开始证书 [微软数据序列化] ——结束证书 打开chrome浏览器(这一步可能也适用于其他浏览器) settings >显示高级设置> HTTPS/SSL >管理证书 在步骤1中导入.txt文件 选择并导出Base-64编码格式的证书。保存为。cer 现在可以使用keytool或Portecle将其导入java密钥存储库

下面是我一直用于以编程方式将.cer文件导入到新的KeyStore中的代码。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
//VERY IMPORTANT.  SOME OF THESE EXIST IN MORE THAN ONE PACKAGE!
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

//Put everything after here in your function.
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);//Make an empty store
InputStream fis = /* insert your file path here */;
BufferedInputStream bis = new BufferedInputStream(fis);

CertificateFactory cf = CertificateFactory.getInstance("X.509");

while (bis.available() > 0) {
    Certificate cert = cf.generateCertificate(bis);
    trustStore.setCertificateEntry("fiddler"+bis.available(), cert);
}

一个开放源码的GUI工具可以在keystore-explorer.org上获得

密钥存储库浏览器 KeyStore资源管理器是Java的开源GUI替代品 命令行实用工具keytool和jarsigner。密钥存储库浏览器 通过直观的图形显示它们的功能 用户界面。

以下画面会有帮助(它们来自官方网站)

运行命令得到的默认屏幕:

shantha@shantha:~$./Downloads/kse-521/kse.sh

点击检查和检查URL选项然后给出你想导入的URL。

如果你给谷歌网站链接,结果窗口将如下所示。

这是用例之一,其余的取决于用户(所有的信用都转到keystore-explorer.org)

您不应该对证书做任何更改。您确定您正在运行正确的导入命令吗?

以下是我的工作:

keytool -import -alias joe -file mycert.cer -keystore mycerts -storepass changeit

mycert的地方。cer包含:

-----BEGIN CERTIFICATE-----
MIIFUTCCBDmgAwIBAgIHK4FgDiVqczANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
...
RLJKd+SjxhLMD2pznKxC/Ztkkcoxaw9u0zVPOPrUtsE/X68Vmv6AEHJ+lWnUaWlf
zLpfMEvelFPYH4NT9mV5wuQ1Pgurf/ydBhPizc0uOCvd6UddJS5rPfVWnuFkgQOk
WmD+yvuojwsL38LPbtrC8SZgPKT3grnLwKu18nm3UN2isuciKPF2spNEFnmCUWDc
MMicbud3twMSO6Zbm3lx6CToNFzP
-----END CERTIFICATE-----

将从浏览器下载的.cer证书文件(打开url并挖掘详细信息)导入到java_home\jre\lib\security中的cacerts密钥存储库中,而不是尝试生成和使用我自己的密钥存储库。

转到java_home\jre\lib\security (Windows)使用cmd和CTRL+SHIFT+ENTER打开管理命令行 2 .执行keytool命令导入证书。 (替换你的aliasname和路径\到\证书。cer)

 ..\..\bin\keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourAliasName -file path\to\certificate.cer

这样您就不必指定任何额外的JVM选项,并且证书应该可以被JRE识别。