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.