我一直在使用 JAVA 开发 WS 客户端,但我遇到了 SSL 身份验证问题。 WS 是在 WCF 上创建的,我无权访问服务器,它们通过 HTTPS 工作并使用需要首先安装在客户端上的客户端证书。服务器人员向我发送了一个 PFX 证书,我在操作系统上成功安装了该证书(我使用的是 OS X),然后我可以通过浏览器访问 WS(我尝试过 Safari 或 FF,以前无法访问 WS ). 我以为操作系统中的任何应用程序都会使用这个证书,但是当我尝试我的 JAVA 应用程序时它不起作用;起初抛出以下错误:
“javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径”
我通过将证书导出到 CER 文件并使用 keytool 命令行工具将证书添加到 JAVA 使用的“cacerts”keyStore 中解决了这个问题。但是在这个错误消失之后开始出现以下内容:“403,禁止”。这显然是因为它没有为站点使用 SSL 客户端证书,但我一直无法找到将它发送给它的方法。任何帮助将不胜感激。
以下是我用来发布到WS的代码:
URL url = new URL(p_url);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", contentType);
OutputStream out = conn.getOutputStream(); // on this line it shows the error
最佳答案
您可以创建一个特定的 SSLContext
(使用 KeyManager
初始化包含您的客户端证书 + 私钥的 keystore ),您可以从中派生一个 SSLSocketFactory
,您将其设置到 HttpsURLConnection
中,或使用全局设置。
您可以设置以下系统属性(用于全局设置):
javax.net.ssl.keyStore=path/to/keystore.pfx
javax.net.ssl.keyStoreType=PKCS12
javax.net.ssl.keyStorePassword=xxxxxxxxx
或者,您可以创建自己的 KeyManagerFactory
/KeyManager
,如 this answer 中所述.
由于您已将服务器证书导入到您的 cacerts
中,因此请将 null
用于 SSLContext 的
(它将获取默认值)。TrustManager[]
参数。 init()
此外,由于您使用的是 OSX,您可以直接使用 KeychainStore
。为此,请使用 ....keyStore=NONE
、keyStoreType=KeychainStore
和 keyStorePassword=-
(任何密码都可以,因为可以访问 key 将在您需要时从操作系统中授予)。不过,我不确定它是否适用于 Lion。请注意,如果您的商店中有多个证书+私钥,它可能会失败(请参阅 this issue )。
关于JAVA - SSL - 客户端证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8948465/