0

I have been looking for answer everywhere and nothing help.

Thats my code :

BufferedImage img1 = ImageIO.read(new File(dir1));
URL url = new URL(image_srcURL);
BufferedImage img2 = 
ImageIO.read(url.openStream());

Now I get the exception below when I'm trying to read the url.

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 java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:198) at java.base/sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1974) at java.base/sun.security.ssl.Handshaker.fatalSE(Handshaker.java:345) at java.base/sun.security.ssl.Handshaker.fatalSE(Handshaker.java:339) at java.base/sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1968) at java.base/sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1777) at java.base/sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:264) at java.base/sun.security.ssl.Handshaker.processLoop(Handshaker.java:1098) at java.base/sun.security.ssl.Handshaker.processRecord(Handshaker.java:1026) at java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1137) at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074) at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) at java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245) at com.folderName.Tools.DataForAutomationV1.compareImg(DFA.java:606) at com.folderName.VendorTests.SettingsPage.editCompDets(SettingsPage.java:562) at com.folderName.VendorTests.SettingsPage.runTest(SettingsPage.java:62) at com.folderName.Vendor.vendorTests(Vendor.java:36) at com.folderName.Main.main(Main.java:40) 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 java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290) at java.base/sun.security.validator.Validator.validate(Validator.java:264) at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:343) at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:226) at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:133) at java.base/sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1947) ... 20 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 26 more

Any help would be great. I'm trying to read an image inside the url and compare it to an existing file. There wasn't any questions here that gave the answer.

Edit:

I've try to enter in my command line " keytool -list -keystore keystore ", but it showed me only trustedCertEntries. No solution worked yet.

Joel
  • 138
  • 10
yakir saadia
  • 68
  • 10
  • Possible duplicate of [Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?](https://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore) – Matteo Baldi Oct 05 '18 at 13:47
  • Looks like you'll need a cert to view the URL. – achAmháin Oct 05 '18 at 13:47
  • Is the url `HTTPS`? – nabster Oct 05 '18 at 13:49
  • @nabster yes it is – yakir saadia Oct 05 '18 at 17:07
  • @MatteoBaldi that questions is about the servers and data he entered inside the server.xml file, I'm looking for a solution used by my java code if there is or better explanation of how to do it in the command line – yakir saadia Oct 05 '18 at 17:11

3 Answers3

0

First you need to obtain the certificate of the server, add it to a keystone file, either to the java truststore in jre or a separate file. If you are creating a new truststore then make sure that you supply truststore to your program

  • How exactly would I know what the cert is? I know that after using the keytool -list command I need to import the ca but it didn't work form me. when I used the keytool all I saw were trustedCertEnteries... – yakir saadia Oct 05 '18 at 18:53
  • Hit the url in the browser, there you can see the certificate. Download it and add it to a truststore using Keytool. – Srikanthkumar Oct 06 '18 at 17:14
0

Below is an example of how I implemented it. The code reads the the response body into an awt BufferedImage, then writes to a .jpg file, then reads the file back into a byte array and then deletes the file. I'm sure I found help with this on SO but I don't have the answer handy. I will try to find that so I can cite. Hope it helps you!

**Edit as @Srikanthkumar mentions in his answer, you will also need to get the cert and add it to your truststore of your JVM. You can get that through a browser via whatever browser you have cert exploring tools.

import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.Base64;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public String getImage(String productNumber) throws EcomWebException {

try {
    BufferedImage image = ImageIO.read(url);
    File file = new File(guid.toString() + ".jpg");
    ImageIO.write(image, "jpg", file);
    String base64ImageString = Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath()));
    file.delete();
    return base64ImageString;
} catch (Exception e) {
    throw new EcomWebException(IMAGE_NOT_FOUND_MESSAGE + productNumber, e);
}
}
Hodglem
  • 614
  • 9
  • 17
  • How would that help me? the exception is thrown when I try to read the image's url because it is in https. about the certificate I responded on Srikanthkumar's answer – yakir saadia Oct 05 '18 at 18:51
  • As mentioned in the edit, and by the other answer, you will need to add the cert from the host to your truststore in the JVM. – Hodglem Oct 05 '18 at 18:55
  • How can I do it? – yakir saadia Oct 05 '18 at 19:30
  • Using Chrome, you can follow this guide to grab the cert https://www.ssl2buy.com/wiki/how-to-view-ssl-certificate-details-on-chrome-56 – Hodglem Oct 05 '18 at 19:42
  • After you get the cert, then you have to place it in the truststore of the JVM. If you are using a container like Tomcat or Weblogic, they each have a truststore themselves. If you are writing an SE application, the cacerts folder where your JVM is located is where to put the cert. – Hodglem Oct 05 '18 at 19:44
  • If I'm using an automation program and the link is always different but the base website is the same it should always work or each time I need to get into the website and do it? – yakir saadia Oct 06 '18 at 09:08
  • Also one more question, is there an option of doing such a thing with java and not with command line? I know there is an option of using System.Property() but when I used it, it didn't work. – yakir saadia Oct 06 '18 at 09:10
  • thanks, I've managed to do it yesterday thanks everyone for your help! – yakir saadia Oct 07 '18 at 18:03
0

The following snippet from this post may help you:

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }

        @Override
        public void checkClientTrusted(
            java.security.cert.X509Certificate[] certs, String authType
        ) {}

        @Override
        public void checkServerTrusted(
            java.security.cert.X509Certificate[] certs, String authType
        ) {}
    }
};

try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());

    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
}
Stphane
  • 3,368
  • 5
  • 32
  • 47