Java Client using FTP over SSL (Explicit)
FTPS extends the FTP protocol with support for SSL and TLS.
Explicit security requires that the FTP client sends an explicit command (AUTH SSL or AUTH TLS) to the FTP server to initiate a secure control connection. The default FTP server port is used. The data connection can also be secured using the commands PBSZ and PROT.
The example code listed below uses Jakarta Commons Net and secures the control connection and data connection using TLS.
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
public class FTPSTest {
public void putFile(String host,
int port,
String username,
String password,
String localFilename,
String remoteFilename) {
try {
FTPSClient ftpClient = new FTPSClient(false);
// Connect to host
ftpClient.connect(host, port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
// Login
if (ftpClient.login(username, password)) {
// Set protection buffer size
ftpClient.execPBSZ(0);
// Set data channel protection to private
ftpClient.execPROT("P");
// Enter local passive mode
ftpClient.enterLocalPassiveMode();
// Store file on host
InputStream is = new FileInputStream(localFilename);
if (ftpClient.storeFile(remoteFilename, is)) {
is.close();
} else {
System.out.println("Could not store file");
}
// Logout
ftpClient.logout();
} else {
System.out.println("FTP login failed");
}
// Disconnect
ftpClient.disconnect();
} else {
System.out.println("FTP connect to host failed");
}
} catch (IOException ioe) {
System.out.println("FTP client received network error");
} catch (NoSuchAlgorithmException nsae) {
System.out.println("FTP client could not use SSL algorithm");
}
}
}
The resulting FTP server log
CONNECT [ 0] - Incoming connection request
CONNECT [ 0] - FTP Connection request accepted
COMMAND [ 0] - AUTH TLS
REPLY [ 0] - 234 Authentication method accepted
CONNECT [ 0] - SSL connection using TLSv1/SSLv3 (RC4-MD5)
CONNECT [ 0] - SSL connection established
COMMAND [ 0] - USER test
REPLY [ 0] - 331 User test, password please
COMMAND [ 0] - PASS ***********
CONNECT [ 0] - Native user 'test' authenticated
REPLY [ 0] - 230 Password Ok, User logged in
COMMAND [ 0] - PBSZ 0
REPLY [ 0] - 200 PBSZ=0
COMMAND [ 0] - PROT P
REPLY [ 0] - 200 PROT P OK, data channel will be secured
COMMAND [ 0] - PASV
REPLY [ 0] - 227 Entering Passive Mode (127,0,0,1,43,41)
COMMAND [ 0] - STOR test.txt
REPLY [ 0] - 150 Opening data connection
CONNECT [ 0] - SSL connection using TLSv1/SSLv3 (RC4-MD5)
CONNECT [ 0] - SSL data connection established
SYSTEM [ 0] - Successfully stored file at 'c:\ftp\test.txt'
REPLY [ 0] - 226 Transfer complete
COMMAND [ 0] - QUIT
CONNECT [ 0] - Connection terminated
==============
http://www.iteye.com/problems/69716
package examples.ftp;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.NoSuchAlgorithmException;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
public final class FTPSExample {
public static final String USAGE = "Usage: ftp [-s] [-b] <127.0.0.1> <shanming> <shanming> <test.txt> <shanming.txt>\n"
+ "\nDefault behavior is to download a file and use ASCII transfer mode.\n"
+ "\t-s store file on server (upload)\n"
+ "\t-b use binary transfer mode\n";
public static final void main(String[] args)
throws NoSuchAlgorithmException {
int base = 0;
boolean storeFile = false, binaryTransfer = false, error = false;
String server, username, password, remote, local;
String protocol = "SSL"; // SSL/TLS
FTPClient ftps;
for (base = 0; base < args.length; base++) {
if (args[base].startsWith("-s"))
storeFile = true;
else if (args[base].startsWith("-b"))
binaryTransfer = true;
else
break;
}
if ((args.length - base) != 5) {
System.err.println(USAGE);
System.exit(1);
}
server = args[base++];
username = args[base++];
password = args[base++];
remote = args[base++];
local = args[base];
ftps = new FTPSClient(protocol);
ftps.enterLocalPassiveMode();
ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
try {
int reply;
ftps.connect(server);
System.out.println("Connected to " + server + ".");
// After connection attempt, you should check the reply code to verify
// success.
reply = ftps.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftps.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
} catch (IOException e) {
if (ftps.isConnected()) {
try {
ftps.disconnect();
} catch (IOException f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
__main: try {
ftps.setBufferSize(1000);
if (!ftps.login(username, password,"990")) {
ftps.logout();
error = true;
break __main;
}
System.out.println("Remote system is: " + ftps.getSystemName());
System.out.println("Working directory is: " + ftps.printWorkingDirectory());
System.out.println("default port is: " + ftps.getDefaultPort());
//if (binaryTransfer)
//ftps.setFileType(FTP.BINARY_FILE_TYPE);
// Use passive mode as default because most of us are
// behind firewalls these days.
SocketFactory factory = SSLSocketFactory.getDefault();
ftps.setSocketFactory(factory);
FTPFile[] files=ftps.listFiles();
for(FTPFile file:files){
System.out.println("ftpfile name is :" + file.getName());
}
if (storeFile) {
System.out.println("Here is upload!");
ftps.changeWorkingDirectory("/");
InputStream input;
input = new FileInputStream(local);
ftps.storeFile(remote, input);
input.close();
} else {
System.out.println("Here is download!");
ftps.changeWorkingDirectory("/");
OutputStream output;
output = new FileOutputStream(local);
ftps.retrieveFile(remote, output);
output.close();
}
ftps.logout();
} catch (FTPConnectionClosedException e)
{
error = true;
System.err.println("Server closed connection.");
e.printStackTrace();
} catch (IOException e) {
error = true;
e.printStackTrace();
} finally {
if (ftps.isConnected()) {
try {
ftps.disconnect();
} catch (IOException f)
{
// do nothing
}
}
}
System.exit(error ? 1 : 0);
} // end main
}
==============================
输出结果:
220-FileZilla Server version 0.9.39 beta
220-written by Tim Kosse (Tim.Kosse@gmx.de)
220 Please visit http://sourceforge.net/projects/filezilla/
AUTH TLS
234 Using authentication type TLS
Connected to 127.0.0.1.
USER shanming
331 Password required for shanming
PASS shanming
230 Logged on
SYST
215 UNIX emulated by FileZilla
Remote system is: UNIX emulated by FileZilla
PWD
257 "/" is current directory.
Working directory is: /
default port is: 21
PORT 127,0,0,1,9,238
200 Port command successful
LIST
521 PROT P required
Here is download!
CWD /
250 CWD successful. "/" is current directory.
PORT 127,0,0,1,9,239
200 Port command successful
RETR ss.txt
521 PROT P required
QUIT
221 Goodbye
=================
http://blog.csdn.net/wangxiaomei2008/article/details/6568007
本例中我们以Apache FTPServer为例进行发布FTPS, 也以Apache FTPClient为例进行客户端连接FTPS。
首先我们启动FTPServer
- package examples.ftpServer;
- import java.io.File;
- import org.apache.ftpserver.FtpServer;
- import org.apache.ftpserver.FtpServerFactory;
- import org.apache.ftpserver.ftplet.FtpException;
- import org.apache.ftpserver.listener.ListenerFactory;
- import org.apache.ftpserver.ssl.SslConfigurationFactory;
- import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
- public class StartFTPS
- {
-
-
-
-
-
- public static void main(String[] args) throws FtpException
- {
-
- FtpServerFactory serverFactory = new FtpServerFactory();
-
- ListenerFactory factory = new ListenerFactory();
-
-
- factory.setPort(2221);
-
- SslConfigurationFactory ssl = new SslConfigurationFactory();
- ssl.setKeystoreFile(new File("F:/FTP/ftpserver-1.0.5/apache-ftpserver-1.0.5/res/kserver.keystore"));
- ssl.setKeystorePassword("123456");
-
-
-
-
-
- factory.setSslConfiguration(ssl.createSslConfiguration());
- factory.setImplicitSsl(true);
-
-
-
- serverFactory.addListener("default", factory.createListener());
-
- PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
- userManagerFactory.setFile(new File("F:/FTP/ftpserver-1.0.5/apache-ftpserver-1.0.5/res/conf/users.properties"));
-
- serverFactory.setUserManager(userManagerFactory.createUserManager());
-
-
- FtpServer server = serverFactory.createServer();
-
- server.start();
- }
- }
然后是客户端连接FTPS
以上实例是经过验证,如果对于其中有些概念性问题或者SSL证书的问题,可以参考先前的文章。