如何使用Java在https连接请求中附加.pfx证书?
我有一个安装在Windows证书存储中的pfx证书,我可以使用C#在https rest调用中附加该证书 现在我需要用Java做同样的事情。我读到了。pfx证书有私钥和一个或多个证书如何使用Java在https连接请求中附加.pfx证书?,java,ssl,https,client-certificates,sslhandshakeexception,Java,Ssl,Https,Client Certificates,Sslhandshakeexception,我有一个安装在Windows证书存储中的pfx证书,我可以使用C#在https rest调用中附加该证书 现在我需要用Java做同样的事情。我读到了。pfx证书有私钥和一个或多个证书 我收到以下错误:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径。 我在Java中尝试过的东西 我使用KeyStore ks=KeyStore.getInstance(“Windows MY”、
我收到以下错误:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径。 我在Java中尝试过的东西
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
public class TestElk {
public static void main(String[] args) throws ClientProtocolException, IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException, NoSuchProviderException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certificateFactory.generateCertificate(new FileInputStream(new File("C:/Work/certi/jre1.8.0_91/lib/security/elkcert.cer")));//exported certificate
/* KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
ks.load(null,null);
Enumeration enumeration = ks.aliases();
while(enumeration.hasMoreElements()) {
String alias = (String)enumeration.nextElement();
System.out.println("alias name: " + alias); }
Certificate[] certificate = ks.getCertificateChain("alias");
*/
// Create TrustStore
KeyStore trustStoreContainingTheCertificate = KeyStore.getInstance(KeyStore.getDefaultType());
trustStoreContainingTheCertificate.load(null, null);
trustStoreContainingTheCertificate.setCertificateEntry("cert", certificate);
// Create SSLContext
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStoreContainingTheCertificate);
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,trustManagerFactory.getTrustManagers(),new SecureRandom());
SSLContext.setDefault(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
URL url = new URL("https://server-link");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
con.setConnectTimeout(10000);
con.setSSLSocketFactory(sslContext.getSocketFactory());
con.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
System.out.println(sb.toString());
//int s= con.getResponseCode(); }
鉴于您已将颁发CA证书(请参阅下面的注释)导入到cacerts文件,以下操作应该可以正常工作,在不同的SO线程中可以找到许多帮助:
“找不到请求目标的有效证书路径”表示根/子CA不受信任。在您的情况下,您不信任为目标“CN=*.dvb.corpinter.net”颁发服务器证书的根目录(MBIS CA)…请根据您的问题更新日志,我无法访问C:驱动器上的链接:)仅添加错误部分。。。。我会发起聊天,但我的声誉还不够,如果“CN=MBIIS CA,OU=MBIIS,O=DAIMLER,C=CN”是“CN=MBIIS CA,OU=MBIIS,O=DAIMLER,C=DE”的子类别,那么您的客户端密钥库需要提供整个链。。。当您从internet explorer导出pfx时,如果我没有弄错的话,您可以包含该链,请查看我在邮件中使用的actual.pfx证书,该证书是我在我们的程序中从clientstore创建keymanager时获得的。它只有一个证书。然后从浏览器中,我可以仅使用前3个选项进行导出。。i、 e.pfx导出已禁用:(.我们如何知道证书是否是另一个证书的子CA,然后如何添加并一起交付。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
public class TestElk {
public static void main(String[] args) throws ClientProtocolException, IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException, NoSuchProviderException {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream(new File("C:/path_to_pfx/mypfx.pfx")), "pfxPass".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, "pfxPass".toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
// Assuming that you imported the CA Cert "Subject: CN=MBIIS CA, OU=MBIIS, O=DAIMLER, C=DE"
// to your cacerts Store.
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("cacerts"), "changeit".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms,tms,new SecureRandom());
SSLContext.setDefault(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
System.setProperty("https.proxyHost", "IP_OF_PROXY_HOST_GOES_HERE");
System.setProperty("https.proxyPort", "PORT_NUMBER_GOES_HERE");
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
URL url = new URL("https://server-link");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
con.setConnectTimeout(10000);
con.setSSLSocketFactory(sslContext.getSocketFactory());
con.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
System.out.println(sb.toString());
//int s= con.getResponseCode();
}
}