我如何使用与HttpsURLConnection的证书认证? [英] How can I use certificate authentication with HttpsURLConnection?

查看:977
本文介绍了我如何使用与HttpsURLConnection的证书认证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图连接到HTTPS URL,但我需要使用客户机认证放置我的系统通过第三方软件来对证书。

I'm trying to connect to an HTTPS URL, but I need to use client authentication with a certificate placed on my system by third party software.

我没有丝毫的想法,我应该如何必须要么找到或使用它,我必须去为C#示例code,它与所有的Java的答案,我发现这个显著不同。 (例如,密钥库需要某种密码显然?)

I haven't the slightest idea how I'm supposed to either find or use it and all I have to go on is C# sample code, which differs significantly with all the Java answers I've found about this. (for instance, the KeyStore needs some sort of password apparently?)

这是C#示例code我有

This is the C# sample code I have

System.Security.Cryptography.X509Certificates.X509CertificateCollection SSC_Certs = 
    new System.Security.Cryptography.X509Certificates.X509CertificateCollection();

Microsoft.Web.Services2.Security.X509.X509CertificateStore WS2_store =
    Microsoft.Web.Services2.Security.X509.X509CertificateStore.CurrentUserStore(
    Microsoft.Web.Services2.Security.X509.X509CertificateStore.MyStore);

WS2_store.OpenRead();

Microsoft.Web.Services2.Security.X509.X509CertificateCollection WS2_store_Certs = WS2_store.Certificates;

然后它在WS2_store_Certs CertificateCollection只是迭代,并检查他们都这样。
远一点,它会设置证书是这样的:

And then it just iterates over the WS2_store_Certs CertificateCollection and checks them all that way. A bit further on, it sets the certificates like this:

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url_string);
httpWebRequest.ClientCertificates = SSC_Certs;

这一切看起来相当合乎逻辑的,即使我不知道它是如何找到的证书,但我仍然没有能够找到相当于Java的这一点。

This all looks fairly logical, even if I have no idea how it finds the certificates, but I still haven't been able to find the Java equivalent of this.

更新

我做的连接是依赖于JDK 5更大的应用程序的一部分,但我已经成功地只使用sunmscapi罐子找到我要找的证书。它的错误,当我尝试使用Windows密钥库虽然连接,所以我想我解决此问题得到了通过得到我从Windows应用商店所需的证书,并在默认的Java 1插入。现在我得到一个EOFException类后跟一个出现SSLHandshakeException说:远程主机关闭握手期间的连接。因为我需要的证书显示在证书链此处的SSL调试跟踪没有揭示一个现实的问题给我,。

The connection I'm making is part of a larger application that depends on JDK 5, but I've managed to just use the sunmscapi jar to find the certificate I'm looking for. It errors when I try to connect using the windows keystore though, so I thought I got around the problem by getting the certificate I need from the windows store and inserting it in the default java one. Now I'm getting an EOFException followed by an SSLHandshakeException saying "Remote host closed connection during handshake". The ssl debug trace doesn't reveal an immediate problem to me, since the certificate I need is displayed in the certificate chain here.

它确实整个ClientKeyExchange的东西,说,它的完成,然后最后的消息我从调试日志得到正确后是

It does the whole ClientKeyExchange thing, says it's finished and then the last messages I get from the debug log right after that are

[write] MD5 and SHA1 hashes:  len = 16
0000: 14 00 00 0C D3 E1 E7 3D   C2 37 2F 41 F9 38 26 CC  .......=.7/A.8&.
Padded plaintext before ENCRYPTION:  len = 32
0000: 14 00 00 0C D3 E1 E7 3D   C2 37 2F 41 F9 38 26 CC  .......=.7/A.8&.
0010: CB 10 05 A1 3D C3 13 1C   EC 39 ED 93 79 9E 4D B0  ....=....9..y.M.
AWT-EventQueue-1, WRITE: TLSv1 Handshake, length = 32
[Raw write]: length = 37
0000: 16 03 01 00 20 06 B1 D8   8F 9B 70 92 F4 AD 0D 91  .... .....p.....
0010: 25 9C 7D 3E 65 C1 8C A7   F7 DA 09 C0 84 FF F4 4A  %..>e..........J
0020: CE FD 4D 65 8D                                     ..Me.
AWT-EventQueue-1, received EOFException: error

和code我用建立的连接

and the code I'm using to set up the connection is

KeyStore jks = KeyStore.getInstance(KeyStore.getDefaultType());
jks.load(null, null);

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
jks.setCertificateEntry("alias", cert1); //X509Certificate obtained from windows keystore
kmf.init(jks, new char[0]);

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);

sslsocketfactory = sslContext.getSocketFactory();
System.setProperty("https.proxyHost", proxyurl);
System.setProperty("https.proxyPort", proxyport);

Authenticator.setDefault(new MyAuthenticator("proxyID", "proxyPassword"));
URL url = new URL(null, urlStr, new sun.net.www.protocol.https.Handler());
HttpsURLConnection uc = (HttpsURLConnection) url.openConnection();
uc.setSSLSocketFactory(sslsocketfactory);
uc.setAllowUserInteraction(true);
uc.setRequestMethod("POST");
uc.connect();

(我没有尝试过的HttpClient但因为我不知道如何找到证书文件,我也不知道这将永远是每个客户端系统上是一样的。)

(I haven't tried HttpClient yet because I have no idea how to find the certificate file and I'm also not sure if this will always be the same on every client system.)

另一个更新

我已经找到了CA来我需要在WINDOWS-ROOT密钥库证书(并与.verify()检查,看看它们都检查了),我已经将它们添加到Java密钥库,以及,但仍没有什么变化。我想他们应该信任库去,但我还没有找到一个办法做到这一点编程。 (请问preFER不依赖于最终用户做这样的事情,因为我可以从他们保证的是,证书和CA的将是present由于在这个开头提到的第三方软件可笑长的问题。)

I've found the CAs for the certificate I need in the WINDOWS-ROOT keystore (and checked with .verify() to see that they all check out), I've added them to the java keystore as well but still nothing changes. I guess they're supposed to go in the TrustStore, but I have yet to find a way to do that programatically. (Would prefer not to rely on end users to do this kind of thing, as all I can guarantee from them is that the certificate and CAs will be present due to the third party software mentioned at the start of this ridiculously long question.)

YET更多的更新

添加在previous更新,我来,我的问题必须位于事实证明我的CA是不是Java的cacerts文件的结论,所以它得到信任的CA从服务器列表中,但不承认他们,随后不发一个证书回导致连接失败。
所以,问题仍然存在,我怎么获取Java要么使用它的密钥库作为信任或证书添加到cacerts中编程(无需文件路径)?因为如果这些都不是可能的,只是给我留下了秘密的选项C,的巫术的。我会开始刺向杜克娃娃针,以防万一。

Adding on the previous update, I've come to the conclusion that my problem must lie in the fact that my CAs are not in Java's cacerts file, so it gets the list of trusted CAs from the server, but doesn't recognise them and subsequently doesn't send a single certificate back causing the connection failure. So the problem remains, how do I get Java to either use it's keystore as truststore or add certificates to cacerts programmatically (without the need for file paths)? Because if those aren't possible that just leaves me with secret option C, voodoo. I'll start stabbing a Duke doll with needles, just in case.

推荐答案

横空出世,因为它被设置为不可导出是一个私人的关键问题。由于这意味着我只能得到Windows应用商店的私钥,我妥协了很多瞎搞让没有太多影响应用程序的其余工作所需的JDK6类和固定的问题。

Turned out to be a Private Key issue since it was set as not exportable. As this meant I could only get the private key from the windows store, I caved and "Fixed" the issue with a lot of messing around to get the necessary jdk6 classes working without influencing the rest of the application too much.

这篇关于我如何使用与HttpsURLConnection的证书认证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆