当前位置: 首页 > 面试题库 >

如何在HttpsURLConnection中使用证书身份验证?

澹台聪
2023-03-14
问题内容

我正在尝试连接到HTTPS URL,但是我需要使用客户端身份验证以及第三方软件在我的系统上放置的证书。

我丝毫不知道如何找到或使用它,我所要做的只是C#示例代码,这与我为此找到的所有Java答案都大不相同。(例如,KeyStore显然需要某种密码吗?)

这是我拥有的C#示例代码

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并一路检查它们。再进一步,它将像下面这样设置证书:

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

即使我不知道它如何找到证书,这一切看起来也很合逻辑,但是我仍然找不到与之等效的Java。

更新

我建立的连接是依赖于JDK 5的较大应用程序的一部分,但我设法仅使用sunmscapi
jar来查找所需的证书。但是,当我尝试使用Windows密钥库进行连接时,它会出错,因此我想通过从Windows存储库中获取所需的证书并将其插入默认的Java证书中来解决此问题。现在,我得到一个EOFException,然后是一个SSLHandshakeException,上面写着“握手期间远程主机关闭连接”。ssl调试跟踪不会对我立即显示问题,因为我所需的证书显示在此处的证书链中。

它完成了整个ClientKeyExchange的工作,说完成了,然后我从调试日志中获得的最后一条消息是

[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

我用来建立连接的代码是

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,因为我不知道如何查找证书文件,而且我不确定在每个客户端系统上是否总是一样。)

另一个更新

我已经在WINDOWS-
ROOT密钥库中找到了我需要的证书的CA(并使用.verify()进行了检查,以查看它们都已签出),我也将它们添加到了Java密钥库中,但是仍然没有任何更改。我猜他们应该放在TrustStore中,但是我还没有找到一种以编程方式执行此操作的方法。(不希望最终用户去做这种事情,因为我可以向他们保证的是,由于这个荒谬的问题开始时提到了第三方软件,因此证书和CA将存在。)

还有更多更新

在上一个更新的基础上,我得出的结论是,我的问题必须在于我的CA不在Java的cacerts文件中,因此它从服务器获取了受信任CA的列表,但无法识别它们,并且随后不会发回导致连接失败的单个证书。因此问题仍然存在,如何让Java将其密钥库用作信任库或以编程方式向cacerts添加证书(无需文件路径)?因为如果不可能,那么我只能选择秘密选项C,即
voodoo 。为了防万一,我将开始用针刺伤杜克娃娃。


问题答案:

事实证明这是一个私钥问题,因为它被设置为不可导出。因为这意味着我只能从Windows商店中获取私钥,所以我花了很多时间弄乱并“解决”了这个问题,以使必要的jdk6类正常工作,而又不会对应用程序的其余部分造成太大影响。



 类似资料:
  • 我想构建一个API路由,经过身份验证的用户和未经身份验证的用户都可以调用该路由,并根据用户是否经过身份验证返回数据。 我卡在使用身份验证::检查()。 控制器的功能是这样的: 我最后有两个场景: 情景1 在这种情况下,在控制器中,当我检查Auth::check()在if条件内时,无论用户是否经过身份验证,我总是得到错误条件。 方案 2 在这种情况下,在控制器中,当我检查Auth::check()时

  • 问题内容: 如何在AngularJs中使用基本身份验证?我已经在Google上搜索了,但是资源对我来说不起作用。我 非常 新AngularJS 问题答案: 假设您的html定义如下: 您可以使用以下基本身份验证将后端连接到rest api: 请注意,此代码的大部分是方法。如果不需要支持IE9及更低版本,则可以将其替换为本地JS实现- atob()和btoa():https : //develope

  • 我不熟悉SSL和证书。我一直在做关于客户端证书认证的研究。我看过这个和wiki。 因此,如果我必须为我的B2B REST服务实现客户端证书身份验证解决方案,我应该执行以下操作 要求客户端生成自己的私钥,并为其公钥生成证书(CA 颁发?)。通过电子邮件或 USB 闪存盘发送该证书。 在服务器端将客户端的公共证书导入信任存储区并启用客户端身份验证 在握手期间,客户端会出示其证书并进行身份验证,因为服务

  • 问题内容: 有谁知道如何在laravel 5.2中使用多重身份验证! 我想使用它,但我不知道如何? 没有人有教程或项目设置多重身份验证吗? 问题答案: 您需要两个表,并 在命令后运行Run命令以创建内置身份验证 两种模型:Users(已存在)和Admin 现在打开config / auth.php并进行以下更改 创建一个新的中间件 Kernel.php中的更改 创建一个新文件夹Http / Con

  • 我对使用证书和安全性是一个新手,所以请原谅我,如果这对其他人来说是一个不需要考虑的问题。我遵循了本指南,将Grails应用程序设置为使用自签名证书在HTTPS上运行。 我试图与运行在同一台机器上的另一个HTTPS网络(一个Nifi独立实例)建立双向SSL。我可以让Nifi实例通过HTTPS与Grails对话,但Grails与Nifi对话(特别是与ListenHTTP处理器对话)时遇到了问题。 当我

  • 假设我们有以下部分的web安全配置: