0

First of all, I know this was asked before but I'e tried the solutions proposed and got no results.

I'm trying to develop a simple program in java where it connects to a website and reads from a text file hosted there. At first I thought the certificate would cause problems because I can't open the website on firefox without receiving a warning. Internet explorer doesn't create any issue. The code is the following:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.*;

public class insig
{
    public static void main(String[] args) throws IOException
    {
        URL fpath           = new URL("website/test.txt");
        BufferedReader br   = new BufferedReader(new InputStreamReader(fpath.openStream()));

        String Reader = null;

        while((Reader = br.readLine()) != null)
        {
            System.out.println(Reader);
        }
    }
}

The first thing I tried was the solution presented on Java: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target, with no sucess. Tried to debug, and although I do not understand this really well, with the help of this http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html I was able to understand that everthing goes accordingly until the part of finding a trusted certificate. Already checked if I added the certificate to the correct version of the jre and still have the same problem.

Could the problem be solved with the website owner? It just because this won't be run only in my PC, so it is not convenient to configure everything again on every PC this runs.

Community
  • 1
  • 1
Hugo Torres
  • 308
  • 4
  • 13

2 Answers2

1

Could the problem be solved with the website owner? It just because this won't be run only in my PC, so it is not convenient to configure everything again on every PC this runs.

There is nothing about website owner and you have to configure certificate store for Java on every PC. Of course it should no be necessary JRE trust store. It can be another one packaged with your application. On top it can be configured through java -Djavax.net.ssl.trustStore (keyStore) parameters Please look here: java-ssl-and-cert-keystore

BTW: There are other options to set Trust/Key stores in Runtime for your specific URL, as well.

ADDED: please read all of that java-and-https-url-connection-without-downloading-certificate

and decide what is good for you.

Community
  • 1
  • 1
Vadim
  • 4,027
  • 2
  • 10
  • 26
  • Would it be possible to, at the start of my code, configure this in the PC where the file is running? – Hugo Torres Dec 05 '16 at 15:47
  • yes it is possible, but it is much easier to supply needed trust store with your program and set it in java command line. Anyway to run your program you have to have java command to be executed. So trust store will be just two parameters in start script. There is only one concern: password to trust store will be open text in that line. But, if you need only one public certificate from one web site it is not a case. – Vadim Dec 05 '16 at 16:03
  • thank ou for your help. In my case, I just need the program to read a file online, so even if the information is not right, it will be noticeable, since come errors will trigger, In ths scenario, what is the worst thing that can happen if I ignore the certificates? – Hugo Torres Dec 06 '16 at 09:07
  • Problem will be only if some "guy-in-the-middle" puts some fake site with fake data in place of your real web-site and you will get not what you want, but what that guy provides. Also it is not hard to check certificate from website in custom code and trust it instead of have it in keystore and allow Java to do it for you. It is just about - write that custom code or not? Put certificate in truststore - no special code needed. Do it on your own - need to write a code. (Not big actually). So, it is up to you. – Vadim Dec 06 '16 at 14:27
  • the problem is that I have already added the root certificate and the problem keeps happening, so I don't even know what the real issue is. How do I check the certificate and add it only with code? All the solutions I find ask to add it via command prompt... – Hugo Torres Dec 06 '16 at 14:43
  • finally understood what was wrong, the certificate was not the right one. I have another difficult but I'll open another thread fr it ;) – Hugo Torres Dec 06 '16 at 16:06
0

Again, there are three ways:

  1. add certificate chain in JRE store (yes with keytool command).

  2. create your own store (again with keytool) ships it with your program and set it as -D property.

  3. Create your own validation.

As in link I gave you see my comments:

// 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) {
         //Vadim: here is the place to check client certs and throw an exception if certs are wrong. When there is nothing all certs accepted. 
        }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
         //Vadim: here is the place to check server certs and throw an exception if certs are wrong. When there is nothing all certs accepted. 
        }
    } };
    // Install the all-trusting trust manager
    final 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) {
            // Here is the palce to check host name against to certificate owner
            return true;
        }
    };

    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

    URL url = new URL("https://www.google.com");

If you will use it as is there will not be any cert validations - all certs and all hosts accepted.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Vadim
  • 4,027
  • 2
  • 10
  • 26