I have an external SOAP server with which I must connect to more https. I donβt want to use keytool to import the two .cer files I received from them, so I want to import them programmatically.
The exception that I get is sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The code I use to import certificates
@Bean
public WSClient wsClient(Jaxb2Marshaller marshaller) throws Exception {
WSClient client = new WSClient();
client.setDefaultUri(getClientUrl());
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null);
createKeyStoreFromResource(ks, keyStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(ks, null);
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
ts.load(null);
createKeyStoreFromResource(ts, trustStore);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(ts);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
messageSender.setKeyManagers(keyManagerFactory.getKeyManagers());
messageSender.setTrustManagers(trustManagerFactory.getTrustManagers());
messageSender.setSslSocketFactory(sslContext.getSocketFactory());
messageSender.setSslProtocol(sslContext.getProtocol());
messageSender.setSslProvider(sslContext.getProvider().getName());
messageSender.setHostnameVerifier((hostname, sslSession) -> true);
client.setMessageSender(messageSender);
return client;
}
private void createKeyStoreFromResource(KeyStore ks, Resource resource)
throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
BufferedInputStream bis = new BufferedInputStream(resource.getInputStream());
while(bis.available() > 0) {
Certificate certificate = cf.generateCertificate(bis);
ks.setCertificateEntry("fiddler" + bis.available(), certificate);
}
}
And then I have public class WSClient extends WebServiceGatewaySupportwhere I usegetWebServiceTemplate().marshalSendAndReceive()
keyStoreand trustStoreare two Resource, files located on the path to classes with the extension.cer
keyStoreThe .cer file has the following format
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
.
.
.
trustStoreThe .cer file has the following format:
...
source
share