我正在构建一个必须调用两个Web服务的服务器。 Web服务具有相同的CA证书(PKCS12)。
第一个接收GET请求,另一个接收SOAP调用。
遵循为GET请求创建连接的代码的一部分
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:无法找到请求目标的有效证书路径
答案 0 :(得分:0)
以下是如何为HTTPS连接创建ssl上下文。
SSLSocketFactory socketFactory = createSSLContext().getSocketFactory();
HttpsURLConnection connection = (HttpsURLConnection) (url).openConnection();
connection.setSSLSocketFactory(socketFactory);
创建SSL上下文的方法。注意,它从.pem文件(x509格式)加载根服务器证书,从.p12(pkcs12格式)加载客户端证书。如果服务器不需要客户端证书,则为密钥管理器传递null。如果由权限颁发的服务器sertificate(已在$ JRE_HOME / lib / security / cacerts中)作为信任管理器传递null。
还有一个注意事项:在.pem文件中,您应该将根证书存储在服务器证书的PKIX路径中。例如,github.com该网站有PKIX路径CN = github.com
- > CN = DigiCert High Assurance EV CA-1
- > CN = DigiCert High Assurance EV Root CA
- > CN = GTE CyberTrust Global Root
。所以你存储了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;
}