Failed to create service exception javax.xml.ws.WebServiceException: - java

I need desperate help to figure out why my application is not creating a webservice.
Here's my webservice Java class:
#WebService
#Component
public class LoginWs extends AbstractWs
{
private static final Logger logger=MiscUtils.getLogger();
#Autowired
private PersonDao personDao = null;
/**
* Returns PersonTransfer on valid login
* #throws NotAuthorisedException if password is incorrect
*/
public PersonTransfer login(String userNameOrEmailAddress, String password) throws NotAuthorisedException
{
Person person=personDao.findByUserNameOrEmailAddress(userNameOrEmailAddress, true);
if (person != null && person.checkPassword(password))
{
PersonTransfer personTransfer = PersonTransfer.getTransfer(person);
personDao.setLastLogin(person.getId(), new GregorianCalendar());
EventLogDao.logEvent(ActionType.READ_DATA.name(), "LoginWs.login()", "personId=" + person.getId());
return(personTransfer);
}
logger.debug("Login failed : u/p="+userNameOrEmailAddress+"/"+password);
throw(new NotAuthorisedException("Invalid Username/Password"));
}
}
The code that is calling this service is:
public static LoginWs getLoginWs()
{
LoginWsService service = new LoginWsService(buildURL("LoginService"));
LoginWs port = service.getLoginWsPort();
CxfClientUtils.configureClientConnection(port);
return(port);
}
The exception is thrown at :
LoginWsService service = new LoginWsService(buildURL("LoginService"));
Here is the full exception:
Error
javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:65)
at javax.xml.ws.Service.<init>(Service.java:56)
at org.websr.my_server.ws.LoginWsService.<init>(Unknown Source)
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://192.168.2.184:8443/my_server/ws/LoginService?wsdl'.: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
Can someone tell me why it is failing at creating Service itself. In LoginWs method, this line
CxfClientUtils.configureClientConnection(port);
configures the SSL connection but my code is not even getting there. It's trying to connect at
LoginWsService service = new LoginWsService(buildURL("LoginService"));
and failing.
Can someone please tell me what's going on here? Thanks!
cert.pem:
MIID1DCCArygAwIBAgIJAPAlC2JvlPsZMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
VQQGEwJDQTEQMA4GA1UECBMHT250YXJpbzEQMA4GA1UEBxMHVG9yb250bzERMA8G
A1UEChMISW5kaXZpY2ExETAPBgNVBAsTCEluZGl2aWNhMRYwFAYDVQQDEw0xOTIu
MTY4LjIuMTg0MSEwHwYJKoZIhvcNAQkBFhJkaXZ5YUBpbmRpdmljYS5jb20wHhcN
MTIwMTA2MTYxMTQwWhcNMTMwMTA1MTYxMTQwWjCBkjELMAkGA1UEBhMCQ0ExEDAO
BgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xETAPBgNVBAoTCEluZGl2
aWNhMREwDwYDVQQLEwhJbmRpdmljYTEWMBQGA1UEAxMNMTkyLjE2OC4yLjE4NDEh
MB8GCSqGSIb3DQEJARYSZGl2eWFAaW5kaXZpY2EuY29tMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAxY8+fsw2pP4ToHN6XFNli4vOGbt+O/ANsr1A8iJh
nCb6cpQ58xF4pvYmETHrAUpv4zpi31SzZvWYI1tMaCEv9IpcX6Kc1B8NB9sLUnhR
gyblF37rZ7eMmSAXXeDS0CTtDEJoHOkGxoUdCN6N+vZjJ5+ZONiiuLqZ4x4HwBFr
ucIlwl2FkMMSxylg90tttSIyUHGz/p2DvNA2goYih4d89c/FLNpqwku+G3/gnL7U
l0OmNuFwJa/qMjy/V1orfpT8egxxh8DMp+fLAv1gjbeoizUs2bHo9kQSbUSp9Cwb
VDCol9jGI14cBuuEpWSANx2gTekN1ktoxztFPCh7H3OK/wIDAQABoyswKTAPBgNV
HREECDAGhwTAqAK4MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEB
BQUAA4IBAQALvpU0/5gQedlET2+r2MV0oksTmM2hV677yVsrOnGCOnTcgMZHp5i4
A0B24Ed2iDesX60OAViIocQkOiwYTRnubg5SoWyL1nhmaa/98U6M/re8R/bvq6OK
qrzEO6hHOtunJg1HcZDiJZop7R/pM52yRhRoXU6upZEhbPr6Eh+zfysA0TD6uMs7
9k2VeJo++XUvbG3dkVJ9kYhqfx2vC0HiMI4H2eomzl2ymS+R9Kg/9o29K8oCYjDI
jWPbl2hmf2cQuC4gG8GUDZi7zJkFsBuJpD6XgpIVK9zNhg1e89eP0nABupIFqBOI
iz0C+tRB4z4TezPL6yC7BDMY2nJ/Cg5e
vs what the server is actually using:
MIICVTCCAb6gAwIBAgIETr3AxTANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJD
QTEQMA4GA1UECBMHT250YXJpbzEQMA4GA1UEBxMHVG9yb250bzERMA8GA1UEChMI
SW5kaXZpY2ExETAPBgNVBAsTCEluZGl2aWNhMRYwFAYDVQQDEw0xOTIuMTY4LjIu
MTg0MB4XDTExMTExMjAwNDE0MVoXDTIxMTEwOTAwNDE0MVowbzELMAkGA1UEBhMC
Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xETAPBgNVBAoT
CEluZGl2aWNhMREwDwYDVQQLEwhJbmRpdmljYTEWMBQGA1UEAxMNMTkyLjE2OC4y
LjE4NDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzvnBMOM2YpM4Ch0MkesA
ryqX3YD8O22kJJrpRuOMyqgt6fKEDxkcGjiEZ7qLfWbzv3eX9DE0nVeS4m65Ucr2
LLZN6iZoqP8J+AmkSXKapIQpX7tZM5UuTDy82vUdOiYJELB3NSJc/4nkZkTaN8Uj
h3Ph366kRUP+QWiq2y97KKMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBFeOQOKq9u
4nq/IUgNpILrhcpiAP5LB49bCXeTCi8Ls51qUCaezceUQKrWM60a6w8FxQF+yopB
PSqGMrUBHnvewkThgZbS12t5vOEoXnWjOwiXhMhRsk5i9YUh1QCYfOFF23aXNfRu
NLL5svksUHm1IzBJJANnL/YdJHRrR0IEQg==

java.security.cert.CertificateException: No subject alternative names present
It sounds like you're connecting using an IP address directly (and not a host name) to a certificate that doesn't have a Subject Alternative Name entry.
This is of course related to this question:
how to add subject alernative name to ssl certs?
If you've chosen not to use a SAN entry but to rely an a host name in the CN (which you've also configured to resolve to the correct IP address in your client), you must also use it to specify the connection. Your URL builder is probably building a URL that still relies on the IP address.
EDIT: (Following comments)
As I was saying in the answer to the other question linked above, there are (at least) two ways of creating a self-signed cert with a Subject Alt Name for Java:
Using Java 7's keytool
Using OpenSSL, as described here: http://www.crsr.net/Notes/SSL.html
You've chosen the second option (possibly a bit more difficult?). OpenSSL is capable of producing a PKCS#12 file (.p12), which the default Java security providers should be able to use as a keystore directly (although keytool in Java 6 and above is capable of converting them to a JKS store via -importkeystore). To use them directly, use the "PKCS12" store type.
To build a PKCS#12 file, with OpenSSL, using the result of the self-signed certificate generation (assuming the files are called cert.pem for the cert and key.pem for the private key):
openssl pkcs12 -export -in cert.pem -inkey key.pem -out store.p12
Then, configure it in Apache Tomcat using (and restart Tomcat):
<Connector port="8443" ... scheme="https" secure="true"
keystoreFile="/path/to/store.p12"
keystorePass="..." keystoreType="PKCS12" sslProtocol="TLS" />
To extract the content of the cert in the PKCS#12 file:
openssl pkcs12 -in store.p12 -nokeys -clcerts | openssl x509 -text -noout
To check the certificate the server is actually using:
echo "" | openssl s_client -showcerts -connect hostname_or_ip_address:port

The certificate you have posted has an issue.
I can open it directly via Windows and I bet if you open Internet Explorer and type the web service URL and view the certificate via IE you should not have any issue.
BUT for some reason Java can not parse it.
For example if I try to read the certificate via default java libraries:
public static void main(String[] args) throws Exception{
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) f.generateCertificate(new FileInputStream("C:\\certificate.pem"));
System.out.println(certificate);
}
I get parsing exception:
Exception in thread "main" java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Unsupported encoding
at sun.security.provider.X509Factory.engineGenerateCertificate(Unknown Source)
at java.security.cert.CertificateFactory.generateCertificate(Unknown Source)
at test.Test.main(Test.java:15)
Caused by: java.io.IOException: Unsupported encoding
at sun.security.provider.X509Factory.base64_to_binary(Unknown Source)
... 3 more
There is a problem in the decoding from base64.
Trying Bouncy Castle it failed to read it as well.
I have seen before this discrepancy between security libraries and Windows being able to decode certificates while Java's libraries can not.
In your case, your certificate can not be parsed by your web service client that uses java and the exception thrown up from CXF wrappers has the missleading message about subject alternative names.
I can not tell what is the problem with your certificate because I am not very familiar with open ssl.
But if you create (just to verify what I am saying) a new keystore using java tools you should have no problem.

Related

How do I programmatically install a certificate to the windows personal certificate store using Java?

In the windows personal certificate store, I am trying to programmatically install a certificate with the private key(using method setKeyEntry) using Java. But I get an exception when I do that.
Caused by: java.lang.UnsupportedOperationException: Cannot assign the key to the given alias.
at jdk.crypto.mscapi/sun.security.mscapi.CKeyStore.engineSetKeyEntry(CKeyStore.java:405)
at jdk.crypto.mscapi/sun.security.mscapi.CKeyStore$MY.engineSetKeyEntry(CKeyStore.java:57)
Code snippet:
KeyStore userCertStore = KeyStore.getInstance(getValue(CERTIFICATE_STORE_TYPE));
userCertStore.load(null,null);
for (iaik.x509.X509Certificate cert : user.getUserCertificates()) {
userCertStore.setCertificateEntry(cert.getSubjectDN().toString(), cert);
userCertStore.setKeyEntry(cert.getSubjectDN().toString(),user.getUserPrivateKey(cert),new
SecureStringBuffer(new StringBuffer(password)).toCharArray(),user.getUserCertificates());
}
The certificates are already set during setKeyEntry - do not store the certificate using setCertificateEntry.
setCertificateEntry is used to set trusted certificates (of the other party), the setKeyEntry is used to store private keys and the full certificate chain belonging to that private key.
So when you set the private key the alias is already taken by a "trusted certificate".

Spring Boot - Reading x509 client certificate from HTTP request

How to receive a x509 certificate from client? I'm using Java's Spring-Boot-Framework with embedded tomcat. For protyping I configured this with Java SE:
HttpsExchange httpsExchange = (HttpsExchange) httpReq;
name = httpsExchange.getSSLSession().getPeerPrincipal().getName();
A user gave me a reference to do this here (down below)
#RequestMapping(value = "/grab")
public void grabCert(HttpServletRequest servletRequest) {
Certificate[] certs =
(Certificate[]) servletRequest.getAttribute("javax.servlet.request.X509Certificate");
}
But I'm not able to get some certificate! Maybe because I'm using tomcat, and it is handling all SSL-Connections. So that no certificate is receiving my application. What I have to do, to get the clients certificate? The client certificate is used to get https connection. I need some information from the subject of the certificate. Thanks.
You have to get it from the HttpServletRequest.
You can check the answer to this question: How to get the certificate into the X509 filter (Spring Security)?:
No you can't get it that way. You need to grab it from the HttpServletRequest:
X509Certificate[] certs = (X509Certificate[])HttpServletRequest.getAttribute("javax.servlet.request.X509Certificate");
This was the post I was trying to point you to, written by Gandalf.
And this was the original question

Convert X509Certificate to PEM or ASN.1/DER

I have a chain of certificates (X509Certificate []), but I have only one certificate in the chain. I need to get the complete chain.
I have tried the openssl command, but that is not useful here. Can someone please tell me how to:
Convert this X509Certificate to PEM or ASN.1/DER that I can save in my file storage?
Get the complete chain using this certificate?
Edit:
So, code-wise what I'm trying to achieve is something like:
protected static String convertToPem(X509Certificate cert) {
Base64 encoder = new Base64(64);
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
String end_cert = "-----END CERTIFICATE-----";
byte[] derCert = cert.getEncoded();
String pemCertPre = new String(Base64.encodeBase64(derCert));
String pemCert = cert_begin + pemCertPre + end_cert;
return pemCert;
}
But, this is not working. Basically, I'm looking for a method that takes a X509Certificate object and then converts it to a .pem etc, that is saved on the device.
Convert this X509Certificate object to .cer/ .per/ .der that I can save in my file storage?
See, for example, the answer at OpenSSL's rsautl cannot load public key created with PEM_write_RSAPublicKey. It tells you how to convert keys to/from PEM and ASN.1/DER format, and includes a treatment of Traditional Format (a.k.a. SubjectPublicKeyInfo).
If you are not doing it programmatically, then you should search for the answer. There are plenty of off-topic question on how to use the openssl command to convert between ASN.1/DER and PEM. Or ask on Super User, where they specialize in commands and their use.
Get the complete chain using this certificate?
This is a well known problem in PKI called the Which Directory problem. The solution is to have the server or service provide the missing intermediate CA certificates. If you can't validate a web server or service's identity because you are missing intermediate CA certificates, then the server is misconfigured.
Once you have the intermediate CA certificates, you still have to root trust somewhere. You can use the self-signed CA, or one of the intermediates signed by the self-signed CA.
This answer is helpful in troubleshooting a misconfugred server using OpenSSL's s_client: SSL site and browser warning.
Related: if there was a global directory of certificates like the ITU envisioned in X.500, then you would not have the second problem. A relying party or user agent would just fetch the certificate it needed from the directory.
But we lack a central directory, so relying parties and user agents often use the CA Zoo (a.k.a., the local Trust Store or cacerts.pem). This has its own set of problems, like the wrong CA certifying a site or service.
One of the off-shoots is the CA Cartel, where browser are in partnership with the CAs at the CA/Browser Forum. Browser have requirements for inclusion, but they often can't punish a misbehaving CA like Trustwave.
And the browsers have managed to box themselves into a position where the Internet of Things (IoT) will not work because of the browser's reliance/requirements on server certificates signed by a CA.

How to create own trust manager in java for apache httpclient library to ignore certificate in apache httpclient 4.2?

Can somebody tell me how can i ignore the ssl certificate during web service call.
I am calling https weburl to get api response but getting peer not authenticated error.
Old examples are not working as some of methods are deprecated so can somebody tell me/ provide some sample code so that i will not get this error.
I just came to know that the problem is coming due to Certificate.
I am using 3rd party API for db calls & they have ssl certificate for their domain
i.e. www.dbprovider.com (SSL certificate is *.dbprovider.com)
& they created subdomain for us which look like myapp.dbprovider.com
So now the problem is no peer certificate is available when i try to hit through command
openssl s_client -ssl3 -showcerts -connect myapp.dbprovider.com:443
openssl s_client -tls1 -showcerts -connect myapp.dbprovider.com:443
Can somebody tell me what i should now do with it. Is there any control on dbprovider site so that they can provide me some configuration or i have to write code to ignore their certificate (but for ignoring certificate we are not getting their peer certificate)
Use a custom SSLSocketFactory as described here: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e512. One such factory that ignores self-signed certs is EasySSLProtocolSocketFactory.
ProtocolSocketFactory factory = new EasySSLProtocolSocketFactory();
try {
URI uri = new URI(config.getBaseUrl());
int port = uri.getPort();
if (port == -1) {
port = 443;
}
Protocol easyHttps = new Protocol(uri.getScheme(), factory, port);
hostConfiguration.setHost(uri.getHost(), port, easyHttps);
} catch (URISyntaxException e) {
throw new IOException("could not parse URI " + config.getBaseUrl(), e);
}
Source: http://frightanic.com/software-development/self-signed-certificates-in-apache-httpclient/

PKIX path building failed: unable to find valid certification path to requested target

I am calling some HTTPS web service which the following Client:
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
/**
* Handles http and https connections. It sends XML request over http (or https)
* to SOAP web service and receive the XML reply.
*
* #author mhewedy
* #date 30.10.2010
*/
public class HttpWSXmlClient
{
private final String ws_url;
private byte[] requestData;
public HttpWSXmlClient(String wsUrl)
{
this.ws_url = wsUrl;
}
public void readRequest(String xmlRequestFilePath)
{
try
{
InputStream istream = new FileInputStream(xmlRequestFilePath);
byte[] data = stream2Bytes(istream);
istream.close();
this.requestData = data;
} catch (Exception e)
{
throw new RuntimeException(e.getMessage());
}
}
/**
*
* #param ps
* PrintStream object to send the debugging info to.
* #return
* #throws IOException
*/
public byte[] sendAndRecieve(PrintStream ps) throws IOException
{
if (requestData == null)
throw new RuntimeException(
"the request data didn't initialized yet.");
if (ps != null)
ps.println("Request:\n" + new String(requestData));
URL url = new URL(ws_url);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// or HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("content-type", "text/xml");
connection.connect();
OutputStream os = connection.getOutputStream();
os.write(requestData);
InputStream is = connection.getInputStream();
byte[] rply = stream2Bytes(is);
if (ps != null)
ps.println("Response:\n" + new String(rply));
os.close();
is.close();
connection.disconnect();
return rply;
}
public byte[] sendAndRecieve() throws IOException
{
return sendAndRecieve(null);
}
private byte[] stream2Bytes(InputStream istream) throws IOException
{
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
int c;
while ((c = istream.read()) != -1)
{
if (c != 0x0A && c != 0x0D) // prevent new line character from being
// written
{
if (c == 0x09)
c = 0x20; // prevent tab character from being written,
// instead write single space char
outstream.write(c);
}
}
byte[] ret = outstream.toByteArray();
outstream.close();
return ret;
}
}
Test:
public class Test
{
private static final String WS_URL = "https://some_server/path/to/ws";
public static void main(String[] args) throws Exception
{
HttpWSXmlClient client = new HttpWSXmlClient(WS_URL);
client.readRequest("request.xml");
client.sendAndRecieve(System.out);
}
}
I got the following output:
Exception in thread "Main Thread" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:415)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
at com.se.swstest.HttpWSXmlClient.sendAndRecieve(HttpWSXmlClient.java:63)
at com.se.swstest.Test.main(Test.java:11)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:285)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)
... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:280)
... 18 more
Do I need any certificate to be put at jdk/jre/lib/security???
Also, I have a xxx_IE.crt and xxx_FX.crt (for Firefox and IE respectively, and they don't work for the above Java client, so do I need a specific certificate for the Java client?
Thanks.
You need to set certificate to hit this url. use below code to set keystore:
System.setProperty("javax.net.ssl.trustStore","clientTrustStore.key");
System.setProperty("javax.net.ssl.trustStorePassword","qwerty");
Java 8 Solution: I just had this problem and solved it by adding the remote site's certificate to my Java keystore. My solution was based on the solution at the myshittycode blog, which was based on a previous solution in mykong's blog. These blog article solutions boil down to downloading a program called InstallCert, which is a Java class you can run from the command line to obtain the certificate. You then proceed to install the certificate in Java's keystore.
The InstallCert Readme worked perfectly for me. You just need to run the following commands:
javac InstallCert.java
java InstallCert [host]:[port] (Enter the given list number of the certificate you want to add in the list when you run the command - likely just 1)
keytool -exportcert -alias [host]-1 -keystore jssecacerts -storepass changeit -file [host].cer
sudo keytool -importcert -alias [host] -keystore [path to system keystore] -storepass changeit -file [host].cer
See the referenced README file for an example if need be.
If you do not need the SSL security then you might want to switch it off.
/**
* disable SSL
*/
private void disableSslVerification() {
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
}
} };
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
I've run into this a few times and it was due to a certificate chain being incomplete. If you are using the standard java trust store, it may not have a certificate that is needed to complete the certificate chain which is required to validate the certificate of the SSL site you are connecting to.
I ran into this problem with some DigiCert certificates and had to manually add the intermediary cert myself.
Here is the solution that I used for installing a site's public cert into the systems keystore for use.
Download the certificate with the following command:
unix, linux, mac
openssl s_client -connect [host]:[port|443] < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > [host].crt
windows
openssl s_client -connect [host]:[port|443] < NUL | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > [host].crt
That will create a crt that can be used to import into a keystore.
Install the new certificate with the command:
keytool -import -alias "[host]" -keystore [path to keystore] -file [host].crt
This will allow you to import the new cert from the site that is causing the exception.
I had hit this when I was trying to initiate a SOAP request from Java code. What worked for me was:
Get the Server certificate by hitting the URL in browser: http://docs.bvstools.com/home/ssl-documentation/exporting-certificate-authorities-cas-from-a-website
This link has all the steps to get the server certificate
Once you have the server certificate with you follow http://java.globinch.com/enterprise-java/security/pkix-path-building-failed-validation-sun-security-validatorexception/#Valid-Certification-Path-to-Requested-Target .
Copying the text from the link, in case this link dies:
All you need to do to fix this error is to add the server certificate
to your trusted Java key store. First You need to download the
document from the server.
Once you have the certificate in your hard drive you can import it to
the Java trust store. To import the certificate to the trusted Java
key store, you can use the java ‘keytool‘ tool. On command prompt
navigate to JRE bin folder, in my case the path is : C:\Program
Files\Java\jdk1.7.0_75\jre\bin . Then use keytool command as follows
to import the certificate to JRE.
keytool -import -alias _alias_name_ -keystore ..\lib\security\cacerts
-file _path_to_cer_file
It will ask for a password. By default the password is “changeit”. If
the password is different you may not be able to import the
certificate.
This error can also happen if the server only sends its leaf certificate and does not send all the chain certificates needed to build the trust chain to the root CA. Unfortunately this is a common misconfiguration of servers.
Most browsers work around this problem if they already know the missing chain certificate from earlier visits or maybe download the missing certificate if the leaf certificate contains a URL for CA issuers in Authority Information Access (AIA). But this behavior is usually restricted to desktop browsers and other tools simply fail because they cannot build the trust chain.
You can make the JRE to automatically download the intermediate certificate by setting com.sun.security.enableAIAcaIssuers to true
To verify if the server is sending all the chain certificates you can enter the host in the following SSL certificate validation tool https://www.digicert.com/help/
On Mac OS I had to open the server's self-signed certificate with system Keychain Access tool, import it, dobubleclick it and then select "Always trust" (even though I set the same in importer).
Before that, of course I ran java key took with -importcert to import same file to cacert storage.
Thank to #danny-paul answer (https://stackoverflow.com/a/60851862/9239136), i resolved my problem on self-hosted instance.
I use Birt application with Tomcat on Windows Server and it was not able to download pictures from Apache service.
I noticed my Apache configuration was incomplete on Windows Server.
The third line was commented out. I uncommented it, restart Apache and it works.
SSLEngine on
SSLCertificateFile "c:/Apache24/conf/ssl/cert.pem"
SSLCertificateKeyFile "c:/Apache24/conf/ssl/privkey.pem"
SSLCACertificateFile "c:/Apache24/conf/ssl/chain.pem"
For me, I had encountered this error when invoking a webservice call, make sure that the site has a valid ssl, i.e the logo on the side of the url is checked, otherwise need to add the certificate to trusted key store in your machine
I also faced this type of issue.I am using tomcat server then i put endorsed folder in tomcat then its start working.And also i replaced JDK1.6 with 1.7 then also its working.Finally i learn SSL then I resolved this type of issues.First you need to download the certificates from that servie provider server.then you are handshake is successfull.
1.Try to put endorsed folder in your server
Next way
2.use jdk1.7
Next
3.Try to download valid certificates using SSL

Categories