JAVA - SSL - 客户端证书
Posted
技术标签:
【中文标题】JAVA - SSL - 客户端证书【英文标题】:JAVA - SSL - Client Certifcates 【发布时间】:2012-02-15 10:26:19 【问题描述】:我一直在使用 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 命令行工具将证书添加到“cacerts”keyStore JAVA 使用来解决这个问题。但是在此错误消失后,以下开始出现:“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
【问题讨论】:
【参考方案1】:您可以创建一个特定的SSLContext
(使用包含您的客户端证书+私钥的密钥库初始化的KeyManager
),从中派生一个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.init()
的 TrustManager[]
参数(它将采用默认值)。
此外,由于您使用的是 OSX,您可以直接使用 KeychainStore
。为此,请使用....keyStore=NONE
、keyStoreType=KeychainStore
和keyStorePassword=-
(任何密码都可以,因为当您从操作系统需要时将授予对密钥的访问权限)。不过,我不确定它是否适用于 Lion。请注意,如果您的商店中有多个证书+私钥,它可能会失败(请参阅this issue)。
【讨论】:
如果您对密钥库/信任库感到困惑,您可能需要阅读以下内容:***.com/a/6341566/372643 谢谢,我确实试过了,但我错过了 keyStoreType=PKCS12。【参考方案2】:看来您可能需要设置自己的 SSL SocketFactory,
http://vafer.org/blog/20061010073725/
我认为自 2006 年以来情况有所好转,因此您可能只需要在命令行上指定一堆属性:
http://***.com/questions/875467/java-client-certificates-over-https-ssl
【讨论】:
【参考方案3】:您需要在您的 Java 应用程序中加载他们发送给您的密钥库。
您可以将其作为文件系统从Keystore
对象中加载并使用它。阅读此example,尤其是关于KeyManager
的部分,即createKeyManagers
方法。
另一种选择是从 Windows 加载密钥库。阅读Windows-MY提供者
【讨论】:
看来 OP 已经做到了。阅读他问题中的第二段。以上是关于JAVA - SSL - 客户端证书的主要内容,如果未能解决你的问题,请参考以下文章
Java 服务器自签名证书 + 客户端证书和 SSL handshake_failure