android ftp文件转换显式TLS [英] android ftp file tranfer over explicit TLS
问题描述
我在发布这个问题之后,一再尝试着让它工作,但没有成功。
我试图在android中使用apache commons库实现FTP文件传输。通信必须通过显式的TLS认证完成。
我可以成功登录,连接到服务器和列表文件,但每当我尝试获取或存储文件时,即使是2Kb的txt文件,我也会得到一个超时异常,并且具有非常大的超时值。
这是我的代码:
I'm posting this question after have tried over and over again to get it working, with no success. I trying to implement a FTP file transfer in android, using apache commons library. The communication must be done through explicit TLS authentication. I can successfully login, connect to the server and list files, but whenever i try to get or store a file, I always get a timeout exception, also with very large timeout value, even for a 2Kb txt file. This is my code:
FTPSClient ftpClient = new FTPSClient("TLS", false);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
KeyManagerFactory kmf = getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(null, null);
KeyManager km = kmf.getKeyManagers()[0];
ftpClient.setKeyManager(km);
ftpClient.setBufferSize(1024 * 1024);
ftpClient.setConnectTimeout(900000);
ftpClient.connect(InetAddress.getByName("server ip address"), 990);
// Set protection buffer size
ftpClient.execPBSZ(0);
// // Set data channel protection to private
ftpClient.execPROT("P");
ftpClient.login("user", "password");
ftpClient.changeWorkingDirectory("/");
ftpClient.setSoTimeout(900000);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
buffIn = new BufferedInputStream(new FileInputStream(file.getAbsolutePath()));
//this works
FTPFile[] files = ftpClient.listFiles();
final OutputStream os = new FileOutputStream(finalStoragePath + "/OK.txt");
//this returns immediatly with false result
boolean getResult=ftpClient.retrieveFile("OK.txt", os);
//this always fail for timeout
boolean result = ftpClient.storeFile( picture.getName(), buffIn );
我找不到这个具体情况的例子,所有的例子都是关于正常的FTP连接,我可以实现没有问题。你们有没有类似的问题?我真的需要一个解决方案,我必须尽快提供这个项目。
I can't find any example of this specific situation, all examples out there, are about normal FTP connection, which I can achieve with no problems. Did any of you had a similar problem? I really need a solution, I have to deliver the project ASAP.
谢谢。
推荐答案
我终于找到了一个解决方案,解决方案是将信任管理器设置为接受所有证书。这里是那些遇到类似问题的代码,maby它可以改进和/或优化,但它的工作原理:
I have finally found a solution, the solution was to set the trust manager to accept all certificates. here is the code for those who are experiencing similar problems, maby it can be improved and/or optimized, but it works:
FTPSClient ftpClient = new FTPSClient("TLS", false);
try {
TrustManager[] trustManager = new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
ftpClient.setTrustManager(trustManager[0]);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(null, null);
KeyManager km = kmf.getKeyManagers()[0];
ftpClient.setKeyManager(km);
ftpClient.setBufferSize(1024 * 1024);
ftpClient.setConnectTimeout(100000);
ftpClient.connect(InetAddress.getByName("ipaddress"), 990);
ftpClient.setSoTimeout(100000);
if (ftpClient.login("user", "password")) {
ftpClient.execPBSZ(0);
ftpClient.execPROT("P");
ftpClient.changeWorkingDirectory("/");
// 250 = directory succesfully changed
if (ftpClient.getReplyString().contains("250")) {
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
BufferedInputStream buffIn = null;
for (File picture : pictures) {
buffIn = new BufferedInputStream(new FileInputStream(picture.getAbsolutePath()));
boolean result = ftpClient.storeFile(picture.getName(), buffIn);
try {
buffIn.close();
} catch (Exception e) {
}
if (result)
picture.delete();
}
}
}
} catch (SocketException e) {
Log.e("APPTAG", e.getStackTrace().toString());
} catch (UnknownHostException e) {
Log.e("APPTAG", e.getStackTrace().toString());
} catch (IOException e) {
Log.e("APPTAG", e.getStackTrace().toString());
} catch (Exception e) {
Log.e("APPTAG", e.getStackTrace().toString());
} finally {
try {
ftpClient.logout();
} catch (Exception e2) {
}
try {
ftpClient.disconnect();
} catch (Exception e2) {
}
}
这篇关于android ftp文件转换显式TLS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!