Java SOAP-PKIX路径生成失败
我正在构建一个必须调用两个Web服务的服务器。Web服务具有相同的CA证书(PKCS12) 第一个通过GET接收请求,另一个通过SOAP调用 遵循为GET请求创建连接的部分代码Java SOAP-PKIX路径生成失败,java,soap,pkcs#12,Java,Soap,Pkcs#12,我正在构建一个必须调用两个Web服务的服务器。Web服务具有相同的CA证书(PKCS12) 第一个通过GET接收请求,另一个通过SOAP调用 遵循为GET请求创建连接的部分代码 InputStream inputStream = null; // is https protocol? if (url.getProtocol().toLowerCase().equals("https")) {
InputStream inputStream = null;
// is https protocol?
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
// create connection
HttpsURLConnection httpsUrlConnection = null;
if(proxy != null){
httpsUrlConnection = (HttpsURLConnection) url.openConnection(proxy);
} else {
httpsUrlConnection = (HttpsURLConnection) url.openConnection();
}
// set the check to: do not verify
httpsUrlConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
setHeaders(httpsUrlConnection, headers);
//set del certificato
log.debug("set certificate for get...");
File cerp12 = new File(Utils.getWebAppLocalPath(),"WEB-INF"+String.valueOf(File.separatorChar)+PropConfig.getProperty("cer.p12"));
((HttpsURLConnection) httpsUrlConnection).setSSLSocketFactory(security(cerp12,PropConfig.getProperty("cer.pwd")));
httpsUrlConnection.connect();
inputStream = httpsUrlConnection.getInputStream();
} else {
HttpURLConnection httpUrlConnection = null;
if(proxy != null){
httpUrlConnection = (HttpURLConnection) url.openConnection(proxy);
} else {
httpUrlConnection = (HttpURLConnection) url.openConnection();
}
setHeaders(httpUrlConnection, headers);
inputStream = httpUrlConnection.getInputStream();
}
in = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result.append(inputLine);
}
这部分用于SOAP请求
InputStream inputStream = null;
// is https protocol?
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
// create connection
HttpsURLConnection httpsUrlConnection = null;
if(proxy != null){
httpsUrlConnection = (HttpsURLConnection) url.openConnection(proxy);
} else {
httpsUrlConnection = (HttpsURLConnection) url.openConnection();
}
// set the check to: do not verify
httpsUrlConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
setHeaders(httpsUrlConnection, headers);
//set del certificato
log.debug("set certificate for get...");
File cerp12 = new File(Utils.getWebAppLocalPath(),"WEB-INF"+String.valueOf(File.separatorChar)+PropConfig.getProperty("cer.p12"));
((HttpsURLConnection) httpsUrlConnection).setSSLSocketFactory(security(cerp12,PropConfig.getProperty("cer.pwd")));
httpsUrlConnection.connect();
inputStream = httpsUrlConnection.getInputStream();
} else {
HttpURLConnection httpUrlConnection = null;
if(proxy != null){
httpUrlConnection = (HttpURLConnection) url.openConnection(proxy);
} else {
httpUrlConnection = (HttpURLConnection) url.openConnection();
}
setHeaders(httpUrlConnection, headers);
inputStream = httpUrlConnection.getInputStream();
}
in = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result.append(inputLine);
}
代码几乎相同
对于GET请求,我没有问题,但是对于SOAP请求httpsUrlConnection.connect()代码>抛出
PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径以下是如何为HTTPS连接创建ssl上下文
SSLSocketFactory socketFactory = createSSLContext().getSocketFactory();
HttpsURLConnection connection = (HttpsURLConnection) (url).openConnection();
connection.setSSLSocketFactory(socketFactory);
和方法来创建SSL上下文。注意,它从.pem文件(x509格式)加载根服务器证书,从.p12(pkcs12格式)加载客户端证书。若服务器不需要客户端证书,请为密钥管理器传递null。如果由授权机构颁发的服务器证书(已在$JRE_HOME/lib/security/cacerts中)作为信任管理器传递null
还有一点需要注意:在.pem文件中,您应该将根证书存储在服务器证书的PKIX路径中。例如,github.com该站点具有PKIX路径CN=github.com
->CN=DigiCert高保证EV CA-1
->CN=DigiCert高保证EV根CA
->CN=GTE CyberTrust全局根。因此,您存储了GTE CyberTrust Global Root
private final SSLContext createSSLContext()
throws NoSuchAlgorithmException, KeyStoreException,
CertificateException, IOException,
UnrecoverableKeyException, KeyManagementException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(Config.getString(Config.KEYSTORE_PATH)));
} catch (Exception ex) {
throw new IOException("not found keystore file: " Config.getString(Config.KEYSTORE_PATH), ex);
}
try{
keyStore.load(fis, Config.getString(Config.KEYSTORE_PASSWORD).toCharArray());
}finally {
IOUtils.closeQuietly(fis);
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream(Config.getString(Config.HTTPS_SERVER_CERT));
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null);
try {
X509Certificate cacert = (X509Certificate) cf.generateCertificate(in);
trustStore.setCertificateEntry("alias", cacert);
} finally {
IOUtils.closeQuietly(in);
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, Config.getString(Config.KEYSTORE_PASSWORD).toCharArray());
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}
感谢您的回复,只有一件事:什么是Config.KEYSTORE\u PATH
<代码>p12路径还是密钥库路径?还有,我的配置中的Config.HTTPS\u SERVER\u CERT
?Config.getString(Config.KEYSTORE\u PATH)-属性是什么。在您的例子中,它是PropConfig.getProperty(“cer.p12”)
。HTTPS\u SERVER\u CERT-服务器certifiacte.IOUtils.closequilly的路径(in);从apache utils,您只需关闭FileInputStreamIsHTTPS\u SERVER\u CERT
$JAVA\u HOME\jre\lib\security\cacerts?不,它只是x509格式的证书(只有一个证书),通常它有扩展名.cer、.crt、.pem。任何浏览器都可以以该格式导出证书。但是$JAVA\u HOME\jre\lib\security\cacerts
是密钥库,可以包含多个证书。通常它包含所有根CA证书。它默认在JVM启动时加载。有时服务器使用https自签名证书,java不知道颁发证书的CA是谁,也不连接到该服务器。在这种情况下,您应该将服务url粘贴到浏览器,获取证书并将其存储为.pem文件。