How to use FTPS (introduction)

SSLFTPClient should be used once secure file transfers are required via FTPS. FTPClient and ProFTPClient do not support secure transfers. SSHFTPClient supports the SFTP protocol, which is unrelated to FTPS.

To run the examples on Windows, you can download a free trial of CompleteFTP, a Windows FTPS server, from this link. CompleteFTP also supports SCP and SFTP.

The basic elements of configuring an FTPS connection are:

Validation of Server Certificates

Usage of server validation is strongly recommended since it virtually eliminates the possibility of communicating with the wrong server. While developing code, however, the programmer might like to postpone any possible certificate validation issues by disabling server validation by using setValidateServer(false). Note that server validation should never be disabled on production systems.

When server validation is enabled (which is the default), server certificates are validated when control channels are switched to TLS. This happens when the auth method is called.

The first step in server validation is to check the certificate chain. The certificate of the CA that issued the certificate must be loaded by the client. This is done via the SSLFTPCertificateStore, which is obtained by calling getRootCertificateStore. SSLFTPCertificateStore maintains a list of certificate objects that can be loaded from various file formats such as PEM and Java keystores.

Alternatively, if the certificate was not issued by a CA, then the actual server certificate may be loaded.

The second step in server validation is performed after the certificate chain is checked, and involves the SSLFTPValidator interface. By default, the client instance has a default implementation of this interface set, called SSLFTPStandardValidator.

The SSLFTPStandardValidator performs a number of checks on the server certificate:

  1. Check to see if the client recommends that the certificate should be accepted. This happens if (1) the server's certificate was verified from the root certificates store (see getRootCertificateStore) or (2) server validation has been switched off via setValidateServer(false).
  2. Ensure that the length of the certificate chain is no more than 2, which indicates that the certificate was issued to the server directly by a CA (Certificate Authority).
  3. Check that the CN (Common Name) of the subject of the server certificate matches the server's hostname.
  4. Check that today's date is within the valid period of the certificate.

Regarding 2): Note that the enforced maximum length of the certificate chain can be increased if required. This can be done with the code below:

SSLFTPStandardValidator.MAX_CERTIFICATE_CHAIN_LENGTH = 3;

Sometimes 3), the hostname checking, can be problematic. It can be disabled completely (not recommended) by creating a new instance of SSLFTPStandardValidator, using a constructor that disables hostname checking. Alternatively, another constructor permits the setting of the hostname to check against rather than the server's hostname. The client must be passed the new instance via the setCustomValidator method.

If the above tweaks are not sufficient, a custom validator can be written that implements the SSLFTPValidator interface and does your own validation. This could be quite easily done by subclassing SSLFTPStandardValidator and overwriting some of its protected methods. Again, the client must be passed the instance of the custom validator via the setCustomValidator method.

Loading Client Certificates

In addition to the standard user-name/password authentication, some FTPS servers require clients to present certificates of their own.

To utilize this functionality, the client's certificate and private key must be supplied. The loadClientCertificate method is used to load the client's private key and certificate in PEM format from the supplied file. Alternatively, setClientCertificate can be used to supply a Java Certificate object and PrivateKey.

The topic Obtaining Keys and Certificates for instructions on producing keys and certificates. A general overview of private/public keys is presented in the topic Public Key Cryptography.

Cipher Suites

For a client and a server to be able to communicate they must be able to agree on a common cipher suite. A set of cipher suites are enabled by default and in most cases the server will support one of these, meaning that no action is required by the developer. There may be cases where the server doesn't support any of the enabled cipher-suites. If this happens then the library will throw an exception when authentication takes place. Some servers – particular older servers adhering to the now defunct US export rules – may only support 40 bit encryption. Use of such ciphers is not recommended as they offer relatively poor security. The topic, Selecting Ciphers, offers advice on selection of ciphers.

To obtain a list of currently enabled cipher-suites, use getEnabledCipherSuites. To enable specific ciphers, first disableAllCipherSuites and then use enableCipherSuite to enable the ciphers required.