Wie kann eine Verbindung zum FTPS-Server mit Datenverbindung über dieselbe TLS-Sitzung hergestellt werden?

Umgebung: Ich verwende Sun Java JDK 1.8.0_60 unter 64-Bit-Windows 7 und Spring Integration 4.1.6 (das intern anscheinend Apache Commons Net 3.3 für den FTPS-Zugriff verwendet).

Ich versuche, einen automatischen Download vom FTPS-Server unseres Kunden in unsere Anwendung zu integrieren. Ich habe es mit SFTP-Servern mit Spring Integration ohne Probleme ohne Probleme für andere Clients getan, aber dies ist das erste Mal, dass ein Client die Verwendung von FTPS von uns verlangt, und es war sehr rätselhaft, die Verbindung herzustellen. Während ich in meiner eigentlichen Anwendung Spring Integration mithilfe von XML-Beans konfiguriere, verwende ich den folgenden Testcode, um zu verstehen, was nicht funktioniert (obwohl ich den tatsächlichen Host / Benutzernamen / das Kennwort hier anonymisiere):

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();

Ich führe diesen Code mit @ a-Djavax.net.debug=all, um alle TLS-Debugging-Informationen auszudrucken.

Die Haupt "Kontroll" -Verbindung zum FTPS-Server funktioniert einwandfrei, aber wenn versucht wird, die Datenverbindung für die Liste (oder eine andere Datenverbindung, die ich versucht habe) zu öffnen, erhalte ich einjavax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake, verursacht durchjava.io.EOFException: SSL peer shut down incorrectly. Wenn ich die Schluckausnahmen auskommentiere, fange ich einen Block um dassession.list Befehl, dann kann ich sehen (obwohl die Ausgabe von javax.net.debug), dass der Server die folgende Nachricht gesendet hat, nachdem der SSL-Handshake der Datenverbindung abgelehnt wurde:

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..

Es scheint so, als ob etwas passiert (und dies ist das erste Mal, dass ich mich mit FTPS befasse, obwohl ich mich zuvor mit einfachem FTP befasst habe), dass der Server die Authentifizierung und Verschlüsselung sowohl über die Steuer- als auch über die Datenverbindungen nach einer "normalen" Methode sicherstellt "TLS - Verbindung zum Herstellen der Steuerverbindung und Authentifizierung findet dort statt. Für jede Datenverbindung muss der Client eine Verbindung mit derselben TLS - Sitzung herstellen. Das macht für mich Sinn, wie es funktionieren soll, aber die Apache Commons Net FTPS-Implementierung scheint das nicht zu tun. Es scheint, als würde versucht, eine neue TLS-Sitzung aufzubauen, und der Server lehnt den Versuch ab.

Beyogen aufdiese Frage zum Fortsetzen von SSL-Sitzungen in JSSE scheint, dass Java für jede Host / Post-Kombination eine andere Sitzung annimmt oder erfordert. Meine Hypothese ist, dass die FTPS-Datenverbindung auf einem anderen Port als die Steuerverbindung ist, die vorhandene Sitzung nicht gefunden wird und versucht, eine neue herzustellen, sodass die Verbindung fehlschlägt.

Ich sehe drei Hauptmöglichkeiten:

Der Server entspricht nicht dem FTPS-Standard, da für den Datenport dieselbe TLS-Sitzung wie für den Steuerport erforderlich ist. Ich kann mit FileZilla 3.13.1 eine Verbindung zum Server herstellen (mit demselben Host / Benutzer / Kennwort, das ich in meinem Code verwenden möchte). Der Server identifiziert sich beim Anmelden als "FileZilla Server 0.9.53 beta". Dies ist also möglicherweise eine proprietäre FileZilla-Methode, und ich muss etwas Seltsames tun, um Java davon zu überzeugen, dieselbe TLS-Sitzung zu verwenden.Der Apache Commons Net-Client folgt nicht dem FTPS-Standard und lässt nur eine Teilmenge zu, die das Sichern der Datenverbindungen nicht ermöglicht. Dies erscheint seltsam, da dies die Standardmethode für die Verbindung mit FTPS aus Java heraus ist. Ich vermisse etwas völlig und diagnostiziere das falsch.

Ich würde mich über jede Anweisung freuen, die Sie zur Herstellung einer Verbindung zu einem solchen FTPS-Server geben können. Vielen Dank

Antworten auf die Frage(6)

Ihre Antwort auf die Frage