Я реализовал клиент FTPS (FTP через SSL/TLS) в java, используя структуру apache.commons.net. Он настроен на явную безопасность на порту 21 по умолчанию.
ftpsClient = new FTPSClient(false);
ftpsClient.setTrustManager(getConfiguration().getCertificatesManager());
ftpsClient.connect(getConfiguration().getHostName(), getConfiguration().getPort());
Пока я не применяю аутентификацию клиента на сервере, все работает нормально. Но мне нужно включить аутентификацию клиента, поэтому я применил ее на сервере и настроил свойства клиентской системы:
-Djavax.net.ssl.keyStore="D:/.../ftps-client-auth.keystore"
-Djavax.net.ssl.keyStorePassword="*****"
-Djavax.net.ssl.keyStoreType=JKS
То, что я получил, было таким же, как если бы я не устанавливал свойства системы:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1806)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:986)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:265)
at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:207)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:172)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:192)
В журнале сервера написано:
DEBUG: Client "<my ip address>", "SSL_accept failed: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate"
Вроде правильно - я включил -Djavax.net.debug=all, что показывает, что сервер отправляет список CN, которые он принимает, но клиент отправляет пустую цепочку сертификатов.
- Что я сделал не так?
- Нужно ли программно выполнять некоторые настройки?
- Должны ли сертификаты или закрытый ключ поддерживать что-то особенное для SSL/TLS?