title: Java Rest Client using self-signed Certificate
body: <p>Hello I'm trying to write a little Rest client which accesses our Cloud server (Rest Webservices). The connection is secured with a SSL Client Certificate which if I understand correctly is not signedby any Certification Authority, and am having problems.</p>
  
  <p>I know that the certificate works fine as I can use this in other programming languages (e.g. C#, PHP, etc), and also because I am testing the API using Postman, however I cannot really understand how to do this in Java.</p>
  
  <p>I have tried using the P12 certificate file, and I also have .key and .crt files, but still nothing changed. The .JKS file I have created using keytool.exe, and I presume it is correct (as far as I could understand).</p>
  
  <p>This is the code I am using :</p>
  
  <pre><code>String keyPassphrase = certPwd;
  
          KeyStore keyStore = KeyStore.getInstance("JKS");
          keyStore.load(new FileInputStream("C:\\Test\\Certificate\\idscertificate.jks"), keyPassphrase.toCharArray());
  
          SSLContext sslContext = SSLContexts.custom()
                  .loadKeyMaterial(keyStore, certPwd.toCharArray())
                  .build();
  
          HttpClient httpClient = HttpClients.custom().setSslcontext(sslContext).build();
  
          HttpResponse response = httpClient.execute(new HttpGet(
                  "https://url_that_I_am_using_to_call_my_rest_web_service"));
  </code></pre>
  
  <p>but every time I launch this I get an error:</p>
  
  <p><strong><em>"unable to find valid certification path to requested target".</em></strong> </p>
  
  <p>As far as I could see this is because I don't have a Certification Authority to specify, am I correct?
  Can anyone help me with this?</p>
  
  <p>Thank you all for your help</p>
  
  <p>Tommaso</p>
  
  <p>/*******************
  This is how I imported the P12 into the Keystore. I tried different ways, the last one i tried was:</p>
  
  <p>First created the JKS:
  <strong><em>keytool -genkey -alias myName -keystore c:\Test\Certificate\mykeystoreName.jks</em></strong></p>
  
  <p>then "cleaned up with:
  <strong><em>keytool -delete -alias myName -keystore c:\Test\Certificate\myKeystoreName.jks</em></strong></p>
  
  <p>then imported the P12 file with:
  <strong><em>keytool -v -importkeystore -srckeystore c:\Test\Certificate\idscertificate.p12 -srcstoretype PKCS12 -destkeystore c:\Test\Certificate\myKeystoreName.jks -deststoretype JKS</em></strong></p>
  
  <p>Result obtained:
  <strong><em>Entry for alias idsclientcertificate successfully imported.
  Import command completed:  1 entries successfully imported, 0 entries failed or cancelled</em></strong></p>
  
  <p>and if I check the content of the keystore I find my imported certificate. 
  Nevertheless I still get the same error.</p>
  
  <p>Thank you for your help.</p>
  
  <p>/****************************Update February 8th *******************</p>
  
  <p>Ok I tried everything, but really everything and now slowly giving up... the situation is the following:</p>
  
  <p>using the following code so far:</p>
  
  <pre><code>SSLContextBuilder sslContext = new SSLContextBuilder();
              sslContext.loadKeyMaterial(readKeyStore(), userPwd.toCharArray());
              //sslContext.loadTrustMaterial(readKeyStore(), new TrustSelfSignedStrategy());
  
              SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
              sslContext.build());
  
              CloseableHttpClient client = HttpClients.custom()
                      .setSSLSocketFactory(sslsf)
                      .setSSLHostnameVerifier(new NoopHostnameVerifier())
                      .build();
              HttpGet httpGet = new HttpGet("https://myhost.com/myrest/status");
              httpGet.addHeader("Accept", "application/json;charset=UTF8");
              httpGet.addHeader("Cookie", "sessionids=INeedThis");
              String encoded = Base64.getEncoder().encodeToString((userName+":"+userPwd).getBytes(StandardCharsets.UTF_8));
              httpGet.addHeader("Authorization", "Basic "+encoded);
              httpGet.addHeader("Cache-Control", "no-cache");
  
              HttpResponse response = client.execute(httpGet);
  </code></pre>
  
  <p>Unfortunately still not working. I tried the following: - include my certificate in the default java cacerts, - specify the alias as my host name, - create a new jks, - load the p12 file, still nothing, same error.
  Error Message I get is:</p>
  
  <p><strong><em>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</em></strong></p>
  
  <p>If I don't use a certificate, I get another error indicating that the certificate is missing therefore the certificate is loaded (also I see it in my IDE).</p>
  
  <p>If I use the exact same certificate file from another platform (c# or using a browser) I get the correct response and object (therefore the certificate/password are valid)</p>
  
  <p><strong>Is there any way that I can stop the validation of the certification path?</strong></p>