基于TLS双向验证的java模拟FTPS的Server端和client端

基于TLS双向验证的java模拟FTPS的Server端和client端

一、首先实现加密的Ftp需要创建证书

1、利用jdk自带的keytools工具生成

  • 为了实现消息认证。
  • Server需要:
  • 1)KeyStore: 其中保存服务端的私钥
  • 2)Trust KeyStore:其中保存客户端的授权证书
  • 同样,Client需要:
  • 1)KeyStore:其中保存客户端的私钥
  • 2)Trust KeyStore:其中保存服务端的授权证书

2、步骤

可以参照我另外一篇文章:KeyStore生成秘钥

1)生成服务端私钥,并且导入到服务端KeyStore文件中

keytool -genkey -alias serverkey -keyalg RSA -keystore   E:\FTPConfig\SedTest\kserver.keystore

---过程中,分别需要填写,根据需求自己设置就行

这样 就可以生成kserver.keystore文件

server.keystore是给服务端用的,其中保存着自己的私钥

 2)根据私钥,导出服务端证书

keytool -export -alias serverkey -keystore E:\FTPConfig\SedTest\kserver.keystore -file E:\FTPConfig\SedTest\server.crt

server.crt就是服务端的证书

3)将服务端证书,导入到客户端的Trust KeyStore中

keytool -import -alias serverkey -file E:\FTPConfig\SedTest\server.crt -keystore E:\FTPConfig\SedTest\tclient.keystore

tclient.keystore是给客户端用的,其中保存着受信任的证书

采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中

keytool -genkey -alias clientkey -keyalg RSA -keystore E:\FTPConfig\SedTest\kclient.keystore
keytool -export -alias clientkey -keystore E:\FTPConfig\SedTest\kclient.keystore -file E:\FTPConfig\SedTest\client.crt
keytool -import -alias clientkey -file E:\FTPConfig\SedTest\client.crt -keystore E:\FTPConfig\SedTest\tserver.keystore

如此一来,生成的文件分成两组
服务端保存:kserver.keystore tserver.keystore
客户端保存:kclient.keystore  tclient.kyestore

二、下载Apache FTPServer     (由于一直尝试,此步不确定是否为必须,后经验证不需要这一步的下载)            
可以到官网下载:                官网下载ApacheServer            
将下载下来的压缩包解压到本地                            
然后进入cmd窗口的管理员模式,注意是管理员模式,否则服务可能开启失败

然后输入                                        

service install
ftpd.bat res/conf/ftpd-typical.xml


ftpd.bat res/conf/ftpd-typical.xml(这是启动ftpserver,如果代码实现,这一步不用执行)  

下面附一套实验成功的Server和client

server端

import java.io.File;

import java.util.ArrayList;

import java.util.List;

import org.apache.ftpserver.FtpServer;

import org.apache.ftpserver.FtpServerFactory;

import org.apache.ftpserver.ftplet.Authority;

import org.apache.ftpserver.ftplet.FtpException;

import org.apache.ftpserver.ftplet.UserManager;

import org.apache.ftpserver.listener.ListenerFactory;

import org.apache.ftpserver.ssl.SslConfigurationFactory;

import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;

import org.apache.ftpserver.usermanager.impl.BaseUser;

import org.apache.ftpserver.usermanager.impl.WritePermission;

public class StartFTPS

{

/**

* 通过程序启动FTP with SSL认证,以Apache FTPServer为例

* @param args

* @throws FtpException

* @author ocean

*/

public static void main(String[] args) throws FtpException

{

// TODO Auto-generated method stub

FtpServerFactory serverFactory = new FtpServerFactory();

ListenerFactory factory = new ListenerFactory();

// set the port of the listener

factory.setPort(2121);

// define SSL configuration

SslConfigurationFactory ssl = new SslConfigurationFactory();

ssl.setKeystoreFile(new File("F:/apache-ftpserver-1.2.0-bin/apache-ftpserver-1.2.0/res/kserver.keystore"));

ssl.setKeystorePassword("123456");

ssl.setTruststoreFile(new File("F:/apache-ftpserver-1.2.0-bin/apache-ftpserver-1.2.0/res/tserver.keystore"));

ssl.setTruststorePassword("123456");

// set the SSL configuration for the listener

factory.setSslConfiguration(ssl.createSslConfiguration());

factory.setImplicitSsl(true);

// replace the default listener

serverFactory.addListener("default", factory.createListener());

PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();

userManagerFactory.setFile(new File("F:/apache-ftpserver-1.2.0-bin/apache-ftpserver-1.2.0/res/conf/users.properties"));

BaseUser user = new BaseUser();

//设置用户名

user.setName("testuser");

//设置密码

user.setPassword("123456");

//设置已存在的目录为该用户的主目录

user.setHomeDirectory("F:\\FTPConfig\\FTP");

//用户权限信息

List<Authority> authorities = new ArrayList<Authority>();

//添加写的权限

authorities.add(new WritePermission());

user.setAuthorities(authorities);

UserManager userManager = userManagerFactory.createUserManager();

userManager.save(user);

serverFactory.setUserManager(userManager);

serverFactory.setUserManager(userManagerFactory.createUserManager());

// start the server

FtpServer server = serverFactory.createServer();

server.start();

}

}

client端

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.KeyStore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPSClient;
public class ConnectFTPS
{
 private static FTPSClient ftpsClient;
 private static final String trust_path = "F:/apache-ftpserver-1.2.0-bin/apache-ftpserver-1.2.0/res/kclient.keystore";
 private static final String trust_pw = "123456";
 private static final String key_path = "F:/apache-ftpserver-1.2.0-bin/apache-ftpserver-1.2.0/res/tclient.keystore";
 private static final String key_pw = "123456";
 private static final String serverIP = "127.0.0.1";
 private static final int serverPort = 2121;
 private static final int defaultTimeout = 10000;
 private static final int soTimeout = 900000;
 private static final int dataTimeout = 5000;
 /**
  * 测试连接FTP With SSL,以Apache FTPServer为例
  * @param args
  * @throws Exception
  * @author ocean
  */
 public static void main(String[] args) throws Exception
 {



//  connect("passive");
  FileInputStream fs = new FileInputStream("F:\\apache-ftpserver-1.2.0-bin\\apache-ftpserver-1.2.0\\res\\home\\README.txt");
  System.out.println("storeFile: " + ftpsClient.storeFile("test_file", fs));
  fs.close();
  ftpsClient.disconnect();
 }
  /**
   * 登陆FTP
   * @param active
   * @return
   * @throws Exception
   */
 private static boolean connect(String active) throws Exception
 {
  ftpsClient = new FTPSClient(true);
  ftpsClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
  ftpsClient.setKeyManager(getKeyManager());
//  ftpsClient.setTrustManager(getTrustManager());
  ftpsClient.setDefaultTimeout(defaultTimeout);
  ftpsClient.connect(serverIP, serverPort);

  System.out.println("connect FTP success");
  ftpsClient.setSoTimeout(soTimeout);
  ftpsClient.getReplyCode();
  ftpsClient.execPBSZ(0);
  ftpsClient.execPROT("P");
  ftpsClient.login("testuser", "123456");
  ftpsClient.changeWorkingDirectory("/");
  ftpsClient.setDataTimeout(dataTimeout);
  if (active.equalsIgnoreCase("active"))
  {


   ftpsClient.enterLocalActiveMode();
  } else
  {


   ftpsClient.enterLocalPassiveMode();
  }
  
  return testLink();
 }
 /**
  * 遍历FTP文件
  * @return
  */
 private static boolean testLink()
 {

  long t1 = System.currentTimeMillis();
  try
  {
System.out.println("hello1");
FTPFile[] listFiles = ftpsClient.listFiles();
System.out.println("listFiles()通过");
   System.out.println("List file length:" + ftpsClient.listFiles().length);
  } catch (IOException e)
  {
   System.out.println(e.getMessage());
   long t2 = System.currentTimeMillis();
   long t = (t2 - t1) / 1000;
   System.out.println("t: " + t);
   try
   {
    ftpsClient.disconnect();
   } catch (IOException e1)
   {
    e1.printStackTrace();
   }
   return false;
  }
  return true;
 }
 private static KeyManager getKeyManager() throws Exception
 {
  KeyStore key_ks = KeyStore.getInstance("JKS");
  key_ks.load(new FileInputStream(key_path), key_pw.toCharArray());
  KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
  kmf.init(key_ks, key_pw.toCharArray());
  KeyManager[] km = kmf.getKeyManagers();
  System.out.println("km len: " + km.length);
  return km[0];
 }
 private static TrustManager getTrustManager() throws Exception
 {
  KeyStore trust_ks = KeyStore.getInstance("JKS");
  trust_ks.load(new FileInputStream(trust_path), trust_pw.toCharArray());
  TrustManagerFactory tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  tf.init(trust_ks);
  TrustManager[] tm = tf.getTrustManagers();
  System.out.println("tm len: " + tm.length);
  return tm[0];
 }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值