How can I connect to my FTPS server made with Java?

72 Views Asked by At

I recently created an FTPS server in Java and now I want to connect to it.

Firstly I create a keystore file using Powershell Terminal :

keytool -genkey -alias mykeystore -keyalg RSA -keystore keystore.jks -keysize 2048

Then I certificate using Powershell terminal with this command

$certificate = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=MyRootCA" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "C:\Users\myuser" -KeyUsageProperty Sign -KeyUsage CertSign

And then typed the command :

$certificate | Export-Certificate -FilePath "C:\Users\myuser\MyLocalCertificate.crt"

Once the certificate at my disposal, I tried to create the truststore with the command

keytool -import -alias myTruststore "C:\Users\myuser\myTruststore.jks" -file "C:\Users\myuser\MyLocalCertificate.crt"

And I wrote the requested password.

Finally, in my Java code I started to write the code for the FTPS server:

FtpServerFactory serverFactory = new FtpServerFactory();
ConnectionConfigFactory factory = new ConnectionConfigFactory();

serverFactory.setConnectionConfig(factory.createConnectionConfig());
ListenerFactory ListenerFactory = new ListenerFactory();
ListenerFactory.setPort(port);

SslConfigurationFactory ssl = new SslConfigurationFactory();
ssl.setKeystoreFile(new File("hostkey/keystore.jks"));
ssl.setKeystorePassword("xxx");
ssl.setClientAuthentication("yes");
ssl.setTruststoreFile(new File("hostkey/myTruststore.jks"));
ssl.setTruststorePassword("xxx");
ListenerFactory.setSslConfiguration(ssl.createSslConfiguration());
ListenerFactory.setImplicitSsl(true);
serverFactory.addListener("default", ListenerFactory.createListener());

ListenerFactory.setDataConnectionConfiguration(
        new DataConnectionConfigurationFactory().createDataConnectionConfiguration());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
UserManager um = userManagerFactory.createUserManager();
// Adding code for lookup in database for the users and set their come directory
FtpServer server = serverFactory.createServer();
server.start();

I start it, but when I try to connect to it via Filezilla for example, it asks me to accept the server's certificate : Certificate is bad (42)

My Java log looks like this:

2023-10-12 11:45:49,710 INFO org.apache.ftpserver.listener.nio.FtpLoggingFilter [pool-4-thread-1] CLOSED
2023-10-12 11:45:54,705 INFO org.apache.ftpserver.listener.nio.FtpLoggingFilter [NioProcessor-4] CREATED
2023-10-12 11:45:54,705 INFO org.apache.ftpserver.listener.nio.FtpLoggingFilter [pool-4-thread-2] OPENED
2023-10-12 11:45:54,743 WARN org.apache.ftpserver.listener.nio.FtpLoggingFilter [pool-4-thread-1] EXCEPTION :
javax.net.ssl.SSLHandshakeException: SSL handshake failed.
        at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:580)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114)        
        at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:121)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:634)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.net.ssl.SSLHandshakeException: Empty client certificate chain
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:358)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:305)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1194)  
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1181)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1277)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1264)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1209)
        at org.apache.mina.filter.ssl.SslHandler.doTasks(SslHandler.java:837)
        at org.apache.mina.filter.ssl.SslHandler.handshake(SslHandler.java:606)
        at org.apache.mina.filter.ssl.SslHandler.messageReceived(SslHandler.java:356)
        at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:561)
        ... 15 common frames omitted

From what I understand the Filezilla doesn't send the certificate or keystore. How could I connect then to it?

Could you explain me what am I missing in the Java code or in the Filezilla or even another way, in order to connect to the FTPS server I created?

PS : The FTP (without the ssl part ) server works perfectly fine. I can have my users connect to it, and do all the necessary operations. I struggle here just to connect to the FTPS I created.

0

There are 0 best solutions below