Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: No Trusted Cert error when connecting to Linux FTPS Server using Apache Commons API

  1. #1
    Junior Member
    Join Date
    Mar 2019
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default No Trusted Cert error when connecting to Linux FTPS Server using Apache Commons API

    I'm trying to connect to a couple of Linux FTPS Servers (One is Red Hat 5.11 and the other is Red Hat 6.8), and download files from the Linux FTPS Server to my local Windows Server using org.apache.commons.net.ftp.FTPSClient.

    I'm trying to connect using Apache Commons API in 2 different ways.

    1. Using the first way I can connect to both Linux hosts and successfully download a test file testftps.txt from both the remote Linux servers to my Local Windows server. My connection method for the first one is connectToFtp() as shown in the below code. It uses a certificate.jks that is located in a path that is defined in my Eclipse Java Project Build Path. The file has an encryption password that is used for protecting the private key in the JKS and account id is also associated with the JKS.

    I have created /tmp/testftps.txt files in both Linux hosts hostname1 and hostname2 . I just changed the host variable to point to either hostname1 or hostname2, and it successfully downloads the file testftps.txt from the corresponding host to my local Windows server using the downloadFiles() Function code shown below.



    private void connectToFtp() throws Exception {
        try {
            ftpClient = new FTPSClient("SSL");
            String host = "hostname1";
            String user = "accountid";
            String password = "";
            String jksFileName = "certificate.jks";
            String jksFilePassword = "encryptionpassword";
     
            File jksFile = new File(ClassLoader.getSystemResource(jksFileName).toURI());
            String jksFilename = jksFile.getName();
            ftpClient.setKeyManager(KeyManagerUtils.createClientKeyManager(jksFile, jksFilePassword));
            ftpClient.connect(host, 2121);
            ftpClient.enterLocalPassiveMode();
            ftpClient.login(user, password);
            ftpClient.execPBSZ(0);
            ftpClient.execPROT("P");
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        } catch(Exception e) {
            System.out.println("Failed to connect: Exception=" + e);
            throw e;
        }
    }
     
    public void downloadFiles() throws Exception {
        try {
            String specifiedRemoteFileName = "testftps.txt";
            File localFile = new File(localFilePath + "/" + specifiedRemoteFileName);
            OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localFile));
            String remoteFile = remoteFilePath + "/" + specifiedRemoteFileName;
            boolean downloaded = ftpClient.retrieveFile(remoteFile, outputStream);
            if (downloaded) {
                System.out.println("File has been downloaded successfully to local destination " + localFile.getAbsolutePath());
            } else {
                System.out.println("File " + remoteFile + " was not downloaded from remote server.");
            }
            outputStream.close();
        }
        catch(Exception e) {
            System.out.println("Error during download...");
            throw e;
        }
    }

    2. For the second program I'm using the same certificate.jks , accountid and encryption password, the same Apache Commons API and I'm trying to fetch same testftps.txt from hostname1 and hostname2 to my local Windows VM. For the second method my connection mechanism connectToFtpUsing_TrustStoreKeystore() is slightly different as shown below. Though it uses the same certificate.jks, it gets Truststore , Keystore , uses keyManagetFactory, TrustManagerFactory SSLContext, etc. I'm still using org.apache.commons.net.ftp.FTPSClient object, however with this method the connection works fine for remote Linux FTPS server hostname1 and I'm able to download fine, but for remote Linux FTPS server hostname2 and a few other hosts the program gives Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found as shown below.

    I'd appreciate if you could look at the connection method below and comparing it with the previous method, let me know why the above method connectToFtp() is successfully downloading files from all Linux FTPS Server whereas below connectToFtpUsing_TrustStoreKeystore() connects to only a few FTPS Servers successfully and fails to connect to many servers with the No trusted certificate found ERROR even though both programs use the same CERTIFICATE.JKS file and the same Apache Commons FTPSClient API. How can this be fixed?


    private void connectToFtpUsing_TrustStoreKeystore() throws Exception {
    try {
            ftpClient = new FTPSClient("TLS", Boolean.FALSE);
            KeyStore keyStore = getKeyStore();
            KeyStore trustStore = getTrustStore(keyStore);
            keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
            keyManagerFactory.init(keyStore, "encryptionpassword".toCharArray());
            trustManagerFactory.init(trustStore);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
            FTPSSocketFactory socketFactory = getSocketFactory(sslContext);
            ftpClient.setRemoteVerificationEnabled(false);
            ftpClient.setSocketFactory(socketFactory);
            ftpClient.setNeedClientAuth(false);
            ftpClient.setBufferSize(0);
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setKeyManager(keyManagerFactory.getKeyManagers()[0]);
            ftpClient.setTrustManager(trustManagerFactory.getTrustManagers()[0]);
            ftpClient.connect("hostname", Integer.parseInt("2121"));
            ftpClient.execPBSZ(0);
            ftpClient.execPROT("P");
            ftpClient.login("accountid", "encryptionpassword");
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        } catch(Exception e) {
            System.out.println("Failed to connect using Trustore keystore" + e);
            throw e;
        }
    }
     
    private static KeyStore getKeyStore() throws Exception {
        KeyStore keyStore = KeyStore.getInstance("JKS");
        InputStream inputStream = new FileInputStream(new File("windows path of certificate.jks"));
        keyStore.load(inputStream, "encryptionpassword".toCharArray());
        return keyStore;
    }
     
    private static KeyStore getTrustStore(KeyStore keyStore) throws Exception {
        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(null);
        for (Enumeration < String > t = keyStore.aliases(); t.hasMoreElements();) {
            String alias = t.nextElement();
            if (keyStore.isKeyEntry(alias)) {
                Certificate[] keyStore_certificate = keyStore.getCertificateChain(alias);
                X509Certificate x5091 = (X509Certificate) keyStore_certificate[1];
                trustStore.setCertificateEntry(x5091.getSubjectDN().toString(), x5091);
            }
        }
        return trustStore;
    }
     
    private static FTPSSocketFactory getSocketFactory(SSLContext sslContext) throws Exception {
        FTPSSocketFactory socketFactory = new FTPSSocketFactory(sslContext) {
            public Socket createSocket() throws IOException {
                return new Socket();
            }
        };
        return socketFactory;
    }

    Stack trace of the error I'm getting with the second method:

    Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)Failed to connect using Trustore keystorejavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
     
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
        at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:259)
        at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:205)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:169)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:189)
        at ftps.apache.FTPSUsingApacheComm.connectToFtpUsing_TrustStoreKeystore(FTPSUsingApacheComm.java:160)
        at ftps.apache.FTPSUsingApacheComm.<init>(FTPSUsingApacheComm.java:132)
        at ftps.apache.FTPSUsingApacheCommMain.main(FTPSUsingApacheCommMain.java:27)
    Caused by: sun.security.validator.ValidatorException: No trusted certificate found
        at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:330)
        at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:110)
        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:1185)
        ... 14 more


    Appreciate your HELP GREATLY with above issue.

  2. #2
    Member Helium c2's Avatar
    Join Date
    Nov 2023
    Location
    Kekaha, Kaua'i
    Posts
    117
    Thanks
    1
    Thanked 3 Times in 3 Posts

    Default Re: No Trusted Cert error when connecting to Linux FTPS Server using Apache Commons API

    I think you'll need to buy the whole network setup. This connects to an FTPS servers, but the computer is running on Windows VM. Since you're using Java programming, the system you're on all must be in Java programming structure and not on Windows OS, even though they have a JRE or JVM environment to download from. This still won't work. The whole setup must be reconfigured. It's like you'll be on a new system, Java only and not Windows VM.

    Example, google email is structured in Java programming language. But it connects only to a server from my linux computer to a Windows-Java/google structure. The setup in network has to be in a one-to-one connection. The environment you're thinking of is coming in at too many variable from every where. Not going to work out.
    Last edited by Helium c2; April 3rd, 2024 at 06:19 PM. Reason: add information

Similar Threads

  1. Replies: 0
    Last Post: March 24th, 2019, 06:13 PM
  2. Uploading File to server ( Apache.commons.net)
    By quirell in forum Java Networking
    Replies: 5
    Last Post: November 11th, 2012, 11:06 PM
  3. Replies: 1
    Last Post: June 7th, 2011, 11:53 AM