Я пытаюсь интегрировать с нашим приложением автоматическую загрузку с FTPS-сервера нашего клиента. Я успешно справился с SFTP-серверами с использованием Spring Integration без каких-либо проблем для других клиентов без проблем, но это первый раз, когда клиент требует от нас использования FTPS, и его подключение было очень озадачивающим. Хотя в моем реальном приложении я настраиваю Spring Integration с использованием 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();
Основное «управляющее» соединение с FTPS-сервером работает нормально, но когда оно пытается открыть соединение для передачи данных для списка (или любое другое соединение для передачи данных, которое я пробовал), я получаю сообщение javax. net.ssl.SSLHandshakeException: соединение удаленного хоста закрыто во время рукопожатия, вызванное java.io.EOFException: одноранговый узел SSL завершил работу неправильно. Если я раскомментирую блок перехвата глотания исключений вокруг команды session.list, то я увижу (хотя выходные данные javax.net.debug), что сервер отправил следующее сообщение после отклонения SSL-подтверждения подключения к данным: < /p>
Код: Выделить всё
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..
Исходя из этого вопроса о возобновлении сеансов SSL в JSSE, оказывается, что Java предполагает или требует отдельный сеанс для каждой комбинации хост/пост. Моя гипотеза заключается в том, что, поскольку соединение для передачи данных FTPS находится на другом порту, чем управляющее соединение, оно не находит существующий сеанс и пытается установить новый, поэтому соединение не удается.
Я вижу три основные возможности:
- Сервер не соответствует стандарту FTPS, требуя одного и того же сеанса TLS на порту данных. как на порту управления. Я могу нормально подключиться к серверу (используя тот же хост/пользователя/пароль, который я пытаюсь использовать в своем коде) с помощью FileZilla 3.13.1. Сервер идентифицирует себя как «бета-версия FileZilla Server 0.9.53» при входе в систему, так что, возможно, это какой-то собственный способ работы FileZilla, и мне нужно сделать что-то странное, чтобы убедить Java использовать тот же сеанс TLS.
Клиент Apache Commons Net на самом деле не соответствует стандарту FTPS и допускает только некоторый подмножество, которое не позволяет обеспечить безопасность подключений к данным. Это может показаться странным, поскольку это стандартный способ подключения к FTPS из Java. - Я что-то упускаю и неправильно диагностирую.
Подробнее здесь: https://stackoverflow.com/questions/323 ... ls-session