Search code examples
javaftpftpsapache-commons-netftp-server

I cannot connect to my FTP server by FTPS with Apache FTPSClient with custom SSLContext - getting "Unrecognized SSL message, plaintext connection?"


I am writing program to connecting to FTP server by FTPS.

Source code:

String protocol = "TLS";
String host = "192.168.5.165";
String username = "usr";
String password = "111";
String trustStorePath = "C:/TEMP/truststore";
String trustStorePassword = "111111";
int port = 990;

FTPSClient client = new FTPSClient(protocol);

KeyStore trustStore = loadStore("JKS", new File(trustStorePath), trustStorePassword);
X509TrustManager trustManager = TrustManagerUtils.getDefaultTrustManager(trustStore);

SSLContext ctx = SSLContext.getInstance("TLSv1.1");
ctx.init(null, new TrustManager[] {trustManager}, null);

FTPSSocketFactory socketFactory = new FTPSSocketFactory(ctx);
client.setSocketFactory(socketFactory);

client.addProtocolCommandListener(new PrintCommandListener(new 
PrintWriter(System.out)));
client.connect(host, port);

I imported server's certificate in my trustStore. But after run this code I got this error:

220 Wing FTP Server ready... (UNREGISTERED WING FTP SERVER)
AUTH TLS
234 AUTH command OK. Initializing TLS connection.

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

  at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:710)
  at sun.security.ssl.InputRecord.read(InputRecord.java:527)
  at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
  at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
  at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:269)
  at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:211)
  at org.apache.commons.net.SocketClient.connect(SocketClient.java:183)
  at org.apache.commons.net.SocketClient.connect(SocketClient.java:203)
  at edtesb.remsenergy.FTPSTest.test(FTPSTest.java:63)

What do I do wrong?


Solution

  • It seems to me, that you have overengineered it.

    I'm not sure I can fully understand, what your code does, but I believe that you unintentionally double-encrypt the connection.


    If you really want to connect to an implicit FTPS port 990, just use

    FTPSClient client = new FTPSClient(protocol, true);
    

    or as protocol="TLS" is the default, this will do too:

    FTPSClient client = new FTPSClient(true);
    
    client.connect(host); // 990 is default, with FTPSClient with isImplicit=true
    

    Though as implicit FTPS is obsolete, you better use an explicit FTPS (if supported by your server, most do), by connecting to the default FTP port 21:

    FTPSClient client = new FTPSClient();
    
    client.connect(host);
    

    If you need a custom SSLContext, just use a corresponding overload of FTPSClient, like:

    FTPSClient client = new FTPSClient(ctx);
    
    client.connect(host);