JAVA - SSL - 客户端证书

发布于 2024-12-28 09:57:33 字数 934 浏览 1 评论 0原文

我一直在使用 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

I've been developing a WS client using JAVA and I'm having a problem with SSL authentication. The WS are created on WCF and I have no access to the server, they work through HTTPS and uses a client certificate that needs to be installed on the client first. The server guys sent me a PFX certificate which I successfully installed on the OS (I'm using OS X) and I could then access the WS via a browser (Safari or FF are both that I tried which previously couldn't access the WSs).
I thought any app in the OS would use this certs but when I'm tried my JAVA app it didn't work; at first the following error was being thrown:

"javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"

I solved this by exporting the certificate to a CER file and using the keytool command line tool to add the certificate into the "cacerts" keyStore JAVA uses. But after this error went away the following started appearing: "403, forbidden". This is obviously because it's not using the SSL client cert for the site but I haven't been able to find a way to send it to it. Any help would be appreciated.

The following is the code I use to post to the 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

国粹 2025-01-04 09:57:33

您可以创建一个特定的SSLContext(使用使用包含客户端证书+私钥的密钥库初始化的KeyManager),从中派生一个SSLSocketFactory,将其设置到 HttpsURLConnection 中,或使用全局设置。

您可以设置以下系统属性(对于全局设置):

  • javax.net.ssl.keyStore=path/to/keystore.pfx
  • javax.net.ssl.keyStoreType=PKCS12 code>
  • javax.net.ssl.keyStorePassword=xxxxxxxxx

或者,您可以按照所述创建自己的 KeyManagerFactory/KeyManager这个答案中。

由于您已在 cacerts 中导入服务器证书,因此请使用 null 作为 SSLContext.init() 的 TrustManager[] 参数 (它将采用默认值)。

此外,由于您使用的是 OSX,因此您可以直接使用 KeychainStore。为此,请使用 ....keyStore=NONEkeyStoreType=KeychainStorekeyStorePassword=- (任何密码都可以,因为可以访问当您需要从操作系统获得密钥时,将会授予该密钥)。不过,我不确定它是否适用于 Lion。请注意,如果您的商店中有多个证书+私钥,则可能会失败(请参阅 此问题)。

You can either create a specific SSLContext (using a KeyManager initialised with the keystore containing your client cert + private key), from which you derive an SSLSocketFactory, which you set into your HttpsURLConnection, or use the global settings.

You could set the following system properties (for the global settings):

  • javax.net.ssl.keyStore=path/to/keystore.pfx
  • javax.net.ssl.keyStoreType=PKCS12
  • javax.net.ssl.keyStorePassword=xxxxxxxxx

Alternatively, you can create your own KeyManagerFactory/KeyManager as described in this answer.

Since you've imported the server certificate in your cacerts, use null for the TrustManager[] argument of SSLContext.init() (it will pick up the default values).

In addition, since you're on OSX, you could use the KeychainStore directly. To do so, use ....keyStore=NONE, keyStoreType=KeychainStore and keyStorePassword=- (any password will do, since access to the key will be granted when you need it from the OS). I'm not sure if it works on Lion, though. Note that it may fail if you have more than one cert+private key in your store (see this issue).

泛泛之交 2025-01-04 09:57:33

看起来您可能需要设置自己的 SSL SocketFactory,

http://vafer.org/blog/20061010073725/

我认为自 2006 年以来情况已经变得更好,因此您可能只需要在命令行上指定一堆属性:

http://stackoverflow.com/questions/875467/java-client-certificates-over-https-ssl

Looks like you probably need to set up your own SSL SocketFactory,

http://vafer.org/blog/20061010073725/

I would think things have gotten better since 2006, so you may just need to specify a bunch of properties on the command line:

http://stackoverflow.com/questions/875467/java-client-certificates-over-https-ssl
往事随风而去 2025-01-04 09:57:33

您需要在您的 Java 应用程序中加载他们发送给您的密钥库。
您可以将其作为文件从文件系统加载到 Keystore 对象中并使用它。阅读这个 示例,尤其是关于 KeyManager 的部分,即 createKeyManagers 方法。

另一种选择是从 Windows 加载密钥库。了解 Windows-MY 提供程序

You need to load the keystore they send you in your java application.
You can load it as a file from the file system in a Keystore object and use it. Read this example and especially the part about KeyManager i.e. createKeyManagers method.

Another option would be to load the keystore from windows. Read about Windows-MY provider

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文