Как настроить аутентификацию клиента с помощью apache.commons.net.ftps?

Я реализовал клиент 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?

person Andy    schedule 20.11.2012    source источник
comment
Как вы настроили свой сервер? Возникли проблемы с настройкой сервера, который обеспечивает SSL и аутентификацию клиента. Любая помощь относительно того, что вы использовали для его настройки?   -  person trynacode    schedule 07.08.2017
comment
@trynacode коллега настроил сервер vsftp с аутентификацией клиента. К сожалению, я не знаю, какие настройки он использовал.   -  person Andy    schedule 07.08.2017
comment
Я посмотрю на это тогда, Энди. Спасибо за ответ!   -  person trynacode    schedule 07.08.2017


Ответы (1)


Разобрался: нужно программно установить KeyManager. Установка свойств системы (-Djavax.net.ssl.keyStore, ...) недостаточна, так как фреймворк не использует Suns SSLSocketFactory.

Пример:

ftpsClient = new FTPSClient(false);
ftpsClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
KeyManager keyManager = org.apache.commons.net.util.KeyManagerUtils.createClientKeyManager(new File(keystorePath), keystorePass);
ftpsClient.setKeyManager(keyManager);
ftpsClient.connect(getConfiguration().getHostName(), getConfiguration().getPort());

Вы можете выбрать другого Trust-Manager, например. тот, который основан на хранилище ключей Java. Утилиты также предоставляют метод для этого: .security.KeyStore)" rel="nofollow noreferrer">TrustManagerUtils.getDefaultTrustManager(keystore)

person Andy    schedule 20.11.2012
comment
Что это за getConfiguration(). ?? - person PankajAndroid; 11.07.2016
comment
получить конфигурацию ?? где вы его найдете? - person Wilson Soethe Cursino; 13.02.2018
comment
Я обновил пример. Взгляните на TrustManagerUtils, чтобы создать экземпляр. - person Andy; 14.02.2018