2

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?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Dias
  • 63
  • 1
  • 7
  • This looks strange. You are connecting with an explicit FTPS protocol to an implicit FTPS port 990. Can you connect with any standalone FTP client the same way? Show us the client's verbose log file. – Martin Prikryl Dec 14 '17 at 10:04
  • Even if i connecting by implicit mode(FTPSClient(protocol, true)), i am getting the same error – Dias Dec 14 '17 at 10:39
  • Did you remove the `setSocketFactory`? – Martin Prikryl Dec 14 '17 at 10:42

1 Answers1

0

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);
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thanks so much for your reply. `code` FTPSClient client = new FTPSClient(); client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); client.connect(host); client.login(username, password); client.execPROT("P"); FTPFile[] files = client.listDirectories(); for (FTPFile file : files) { System.out.println(file.getName()); } – Dias Dec 14 '17 at 11:18
  • Thanks so much for your reply. Yes, my server supports explicit ftps and i need to connect to the server by explicit mode. I did what you say. `FTPSClient client = new FTPSClient(); client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); client.connect(host); client.login(username, password); client.execPROT("P"); FTPFile[] files = client.listDirectories(); for (FTPFile file : files) { System.out.println(file.getName()); }` – Dias Dec 14 '17 at 11:47
  • And i am getting this log: `220-FileZilla Server 0.9.60 beta 220 Please visit https://filezilla-project.org/ AUTH TLS 234 Using authentication type TLS USER usr 331 Password required for usr PASS 111 230 Logged on PROT P 200 Protection level set to P SYST 215 UNIX emulated by FileZilla PORT 192,168,5,165,199,26 200 Port command successful LIST 150 Opening data channel for directory listing of "/" Disconnected from the target VM, address: '127.0.0.1:50964', transport: 'socket' javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake ` – Dias Dec 14 '17 at 11:50
  • You now have a different problem. Most probably this one: [When using Java Apache FTPClient for FTP TLS getting “Remote host closed connection during handshake”](https://stackoverflow.com/q/46631315/850848) – Martin Prikryl Dec 14 '17 at 12:12