繁体   English   中英

使用FTPS将文件从android传输到服务器

[英]Transfer files from android with FTPS to the server

我在我的Android应用程序中使用Apache Commons FTP库

我通过FTPS建立连接,虽然它与服务器完美连接,但在传输文件时遇到问题。

出于安全原因,订购应用程序的客户端在使用PROT P时请求在数据连接上恢复TLS会话。

因此,我在服务器上启用了此选项:

在此输入图像描述

正如我所说,我可以连接到服务器,但不能传输文件。 如果我取消激活“使用PROT P时数据连接上所需的TLS会话恢复”框,则传输正常。

我正在寻找一种使用库进行文件传输的方法,但是没有成功,我知道必须有一种方法。

我给你相关代码的一部分:

TransferImagenesFTP.ftpClient = new FTPSClient();

TransferImagenesFTP.ftpClient.connect(InetAddress.getByName("XXX_XXX_XX_X"), 26);
TransferImagenesFTP.ftpClient.enterLocalPassiveMode();
TransferImagenesFTP.ftpClient.setBufferSize(1024000);
TransferImagenesFTP.ftpClient.login("xxxxxx", "zzzzzz");
TransferImagenesFTP.ftpClient.execPROT("P");
TransferImagenesFTP.ftpClient.type(FTP.BINARY_FILE_TYPE);

我感谢任何帮助,谢谢。

您可以尝试以下代码,我希望它也适用于您的情况。

该代码使用Apache Commons vsf2通过安全ftp连接(SFTP)上传文件

try {
  String filepath = "<FILE PATH>";
  String serverAddress = "<FTP SERVER ADDRESS>";
  String userId = "<FTP USER ID>";
  String password = "<FTP PASSWORD>";
  String remoteDirectory = "<FTP DIRECTORY TO UPLOAD TO>";   
  String keyPath = "<PATH TO YOUR KEY>";   
  String passPhrase = "<PASSWORD FOR YOUR KEY>";   


  File file = new File(filepath);
  if (!file.exists())
    throw new RuntimeException("Error. File not found");

  //Initializes the file manager
  StandardFileSystemManager manager = new StandardFileSystemManager();
  manager.init();

  //Setup our SFTP configuration
  FileSystemOptions opts = new FileSystemOptions();
  SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
  SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
  SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);

  // Create local file object
  FileObject localFile = manager.resolveFile(file.getAbsolutePath());

  // Create remote file object
  FileObject remoteFile = manager.resolveFile(createConnectionString(serverAddress, userId, password, keyPath, passPhrase, fileToFTP), createDefaultOptions(keyPath, passPhrase));


  // Copy local file to sftp server
  remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
  System.out.println("File upload successful");

}
catch (Exception ex) {
  ex.printStackTrace();
  return false;
}
finally {
  manager.close();
}

您可以在Apache Commons VFS文档中查看更多信息

编辑

在理解了FTPS背后的逻辑和@ riyaz-ali的帖子之后,并参考了你对本文的评论中的链接

Apache FTP客户端存在问题,它不支持TLS会话恢复。 您可以修补Apache Commons Library的现有实现。

您可以尝试以下代码步骤来使其正常工作:

  1. 在项目中添加以下修补的类。 (此类扩展了Apache commons中给出的补丁中现有的FTPS实现)

     import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.Socket; import java.util.Locale; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import org.apache.commons.net.ftp.FTPSClient; import com.google.common.base.Throwables; public class PatchedFTPSClient extends FTPSClient { @Override protected void _prepareDataSocket_(final Socket socket) throws IOException { if(socket instanceof SSLSocket) { final SSLSession session = ((SSLSocket) _socket_).getSession(); final SSLSessionContext context = session.getSessionContext(); try { final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache"); sessionHostPortCache.setAccessible(true); final Object cache = sessionHostPortCache.get(context); final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class); method.setAccessible(true); final String key = String.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT); method.invoke(cache, key, session); } catch(Exception e) { throw Throwables.propagate(e); } } } } 
  2. 使用此修改后的代码段。

     TransferImagenesFTP.ftpClient = new PatchedFTPSClient(); TransferImagenesFTP.ftpClient.connect(InetAddress.getByName<SERVER-ADDRESS>"), 26); TransferImagenesFTP.ftpClient.login("<USERNAME>", "<PASSWORD>"); TransferImagenesFTP.ftpClient.execPBSZ(0); TransferImagenesFTP.ftpClient.execPROT("P"); TransferImagenesFTP.ftpClient.enterLocalPassiveMode(); //Now use the FTP client to upload the file as usual. 

    希望这对您有用,并将解决您的问题。

在您的情况下,问题是Apache FTPSClient不支持TLS会话恢复,因此,当您尝试传输文件时失败。

理解问题

当您通过TLS连接到FTP服务器时,服务器控制连接上启动与客户端的安全ssl会话 然后,客户端通过发送PASV命令进入被动模式 ,作为响应,服务器打开一个随机的非特权端口,并将端口号发送给客户端。 此端口表示数据连接 现在要安全地连接到这个新端口,客户端必须重新使用它已经与控制连接上的服务器的现有TLS会话。

为什么要重用TLS会话?

不需要会话恢复允许会话窃取攻击。 FTP的问题是数据连接不验证客户端。
如果服务器/客户端不重用现有的TLS会话,则攻击者可能会连接到数据端口并上传恶意软件。 因此,为了防止此类攻击,FTP服务器要求客户端重用已经建立的会话。

在您的情况下, Apache FTPSClient无法重用会话(这是一个已知问题 ),因此服务器认为您的客户端是未经授权的并拒绝传输。

查看Wealthfront文章 ,了解如何修补和示例实现。

资料来源:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM