Как подключиться к серверу FTPS с передачей данных, используя тот же сеанс TLS?

Среда: я использую Sun Java JDK 1.8.0_60 на 64-битной Windows 7, используя Spring Integration 4.1.6 (которая, по-видимому, использует Apache Commons Net 3.3 для доступа FTPS).

Я пытаюсь интегрировать с нашим приложением автоматическую загрузку с сервера FTPS нашего клиента. Я успешно справился с SFTP-серверами, используя Spring Integration без каких-либо проблем для других клиентов без проблем, но это первый раз, когда клиент требует, чтобы мы использовали FTPS, и подключение к нему было очень загадочным. В то время как в моем реальном приложении я настраиваю Spring Integration с использованием bean-компонентов XML, чтобы попытаться понять, что не работает, я использую следующий тестовый код (хотя здесь я анонимизирую фактический хост / имя пользователя / пароль):

final DefaultFtpsSessionFactory sessionFactory = new DefaultFtpsSessionFactory();
sessionFactory.setHost("XXXXXXXXX");
sessionFactory.setPort(990);
sessionFactory.setUsername("XXXXXXX");
sessionFactory.setPassword("XXXXXXX");
sessionFactory.setClientMode(2);
sessionFactory.setFileType(2);
sessionFactory.setUseClientMode(true);
sessionFactory.setImplicit(true);
sessionFactory.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
sessionFactory.setProt("P");
sessionFactory.setProtocol("TLSv1.2");
sessionFactory.setProtocols(new String[]{"TLSv1.2"});
sessionFactory.setSessionCreation(true);
sessionFactory.setCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"});

final FtpSession session = sessionFactory.getSession();
//try {
    final FTPFile[] ftpFiles = session.list("/");
    logger.debug("FtpFiles: {}", (Object[]) ftpFiles);
//} catch (Exception ignored ) {}
session.close();

Я запускаю этот код с-Djavax.net.debug=all чтобы получить всю информацию отладки TLS.

Основное «контрольное» соединение с сервером FTPS работает нормально, но когда он пытается открыть соединение для передачи данных для списка (или любое другое соединение для передачи данных, которое я пробовал), я получаюjavax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake, вызванныйjava.io.EOFException: SSL peer shut down incorrectly, Если я раскомментирую блок захвата исключений глотания вокругsession.list команда, затем я вижу (хотя вывод javax.net.debug), что сервер отправил следующее сообщение после отклонения рукопожатия SSL подключения к данным:

main, READ: TLSv1.2 Application Data, length = 129
Padded plaintext after DECRYPTION:  len = 105
0000: 34 35 30 20 54 4C 53 20   73 65 73 73 69 6F 6E 20  450 TLS session 
0010: 6F 66 20 64 61 74 61 20   63 6F 6E 6E 65 63 74 69  of data connecti
0020: 6F 6E 20 68 61 73 20 6E   6F 74 20 72 65 73 75 6D  on has not resum
0030: 65 64 20 6F 72 20 74 68   65 20 73 65 73 73 69 6F  ed or the sessio
0040: 6E 20 64 6F 65 73 20 6E   6F 74 20 6D 61 74 63 68  n does not match
0050: 20 74 68 65 20 63 6F 6E   74 72 6F 6C 20 63 6F 6E   the control con
0060: 6E 65 63 74 69 6F 6E 0D   0A                       nection..

Похоже, что происходит (и это мой первый раз, когда я имею дело с FTPS, хотя раньше я имел дело с обычным FTP), это то, что сервер обеспечивает аутентификацию и шифрование как для контрольных, так и для подключений к данным, что после «нормального» TLS-соединение для установления контрольного соединения и проверки подлинности происходит там, каждое соединение для передачи данных требует, чтобы клиент подключался к одному и тому же сеансу TLS. Это имеет смысл для меня, так как это должно работать, но реализация Apache Commons Net FTPS, похоже, этого не делает. Кажется, он пытается установить новый сеанс TLS, и поэтому сервер отклоняет попытку.

На основеэтот вопрос о возобновлении сеансов SSL в JSSEПохоже, что Java предполагает или требует другой сеанс для каждой комбинации хост / пост. Моя гипотеза состоит в том, что, поскольку соединение для передачи данных FTPS находится на порте, отличном от контрольного, оно не находит существующий сеанс и пытается установить новый, поэтому соединение не устанавливается.

Я вижу три основные возможности:

Сервер не следует стандарту FTPS, требуя того же сеанса TLS на порте данных, что и на порте управления. Я могу нормально подключиться к серверу (используя тот же хост / пользователя / пароль, который я пытаюсь использовать в своем коде), используя FileZilla 3.13.1. Сервер идентифицирует себя как «FileZilla Server 0.9.53 beta» при входе в систему, так что, возможно, это какой-то проприетарный метод FileZilla, и есть кое-что странное, что мне нужно сделать, чтобы убедить Java использовать тот же сеанс TLS.Клиент Apache Commons Net на самом деле не соответствует стандарту FTPS и допускает только некоторые подмножества, которые не позволяют защищать соединения для передачи данных. Это может показаться странным, так как кажется, что это стандартный способ подключения к FTPS из Java.Я совершенно что-то упускаю и неправильно диагностирую это.

Я был бы признателен за любые указания относительно того, как подключиться к серверу FTPS такого типа. Спасибо.

Ответы на вопрос(0)

Ваш ответ на вопрос