ApacheFTPServer加密传输FTPS的实现(三)

1、FTPS是什么

FTPS是在安全套接层使用标准的FTP协议和指令的一种增强型FTP协议,为FTP协议和数据通道增加了SSL安全功能。FTPS也称作"FTP-SSL"和"FTP-over-SSL"。SSL是一个在客户机和具有SSL功能的服务器之间的安全连接中对数据进行加密和解密的协议。通俗的话说就是在实现FTP传输的功能上再实现数据发送时加密,数据接收时解密,保证数据在传输过程中的安全。

2、为什么FTP不安全,演示数据加密方面

2.1 FTP服务搭建

我们先搭建一个最简单的FTP服务。链接: ApacheFTPServer快速搭建FTP服务由浅入深(一)

2.2 安装网络封包分析软件

网络封包分析软件的功能是撷取网络封包,直接与网卡进行数据报文交换,并尽可能显示出最为详细的网络封包资料。这里我们使用Wireshark来实现网络抓包。需要安装包可以私信我,网络上也有很多。
在这里插入图片描述
安装打开后的页面,选择对应的网卡,开始抓包。
我们先登录上传一个文件,文件内容是
FTPS is an enhanced FTP protocol that uses standard FTP protocols and instructions at the secure socket layer, adding SSL security features to the FTP protocol and data channels. FTPS is also called "FTP-SSL" and "FTP-over-SSL". SSL is a protocol for encrypting and decrypting data in a secure connection between a client and an SSL-capable server. In popular terms, it is to implement the function of FTP transmission and then realize encryption during data transmission and decryption when data is received to ensure the security of data during transmission.
来模拟我们日常使用的数据。
在这里插入图片描述
我们可以看到我们的登录账号密码都是明文在网络传输中,再看看我们上传的数据,找到FTP-DATA协议类型的包,查看包详情。
在这里插入图片描述
在这里插入图片描述
查看FTP Data内容,我们的文本数据都一览无余,对于数据安全要求严格的项目这是不可容忍的。

3、如何避免这种情况

本文倾向于实践且本人水平有限,对各方面专业拓展只做点水。这里我们先了解一下非对称加密,它需要两个密钥来进行加密和解密,公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥) ,公钥加密的信息只有私钥才能解开,私钥加密的信息只有公钥才能解开。这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,所以只要私钥不泄露,那么我们的数据就是安全的。

3.1 准备秘钥对

这里我们用户JDK的keytool生成秘钥对,进入我们本地JDK安装的目录bin下,打开命令窗口
在这里插入图片描述
在这里插入图片描述

#生成服务器用户的秘钥对 文件路径自定义
#特别提醒 设置密码后,在输入您的名字与姓氏是什么这栏,一定要填服务器的域名或者IP地址,切记,这样客户端发送请求时才会根据目标服务器地址找到本地安装的服务器证书,对数据加密
keytool -genkeypair -alias rootca -keyalg RSA -keysize 2048 -validity 365 -keystore E:\FTPConfig\keyserver.keystore
#导出服务器证书,里面包含服务器的公钥,给客户端安装,可以用户服务器的公钥加密数据发送给服务器
keytool -export -alias rootca -keystore E:\FTPConfig\keyserver.keystore -file E:\FTPConfig\server.crt
#将我们的服务器证书添加到我们的信任库中,同时也创建我们的信任库中,方便今后我们管理对客户端的认证维护
keytool -import -v -alias rootca -file E:\FTPConfig\server.crt -keystore E:\FTPConfig\trustserver.keystore
#查看我们的信任库和秘钥库
keytool -list -v -keystore E:\FTPConfig\trustserver.keystore

keytool -list -v -keystore E:\FTPConfig\keyserver.keystore

到这里我们已经生成了服务端的秘钥对、信任库、服务器证书。接下来准备客户端的秘钥对和证书请求。为了方便演示,我们直接用户客户端生成,我用的是SecureFX客户端来实现的,其所需要的安装包和注册机可以私信我。
在这里插入图片描述
在这里插入图片描述
打开主界面,添加连接,设置FTP/TLS(implicit)方式,输入地址,账号信息。
在这里插入图片描述
证书这一栏不勾选全局,自己创建
在这里插入图片描述
在这里插入图片描述
创建好后会生成两个文件,一个是客户端的秘钥库,还有一个是证书请求,里面包含了客户端的信息,公钥,给服务器签名认证用的。
在这里插入图片描述
接下来开始对客户端的证书请求进行认证授权。

#用服务端的秘钥库和客户端的证书请求生成客户端的二级证书
keytool -gencert -alias rootca -keystore E:\FTPConfig\keyserver.keystore -infile E:\FTPConfig\client.csr -outfile E:\FTPConfig\client.crt
#将二级证书添加到,信任库中
keytool -import -v -alias client -file E:\FTPConfig\client.crt -keystore E:\FTPConfig\trustserver.keystore

大功告成,接下来最后一步,启动一个FTPS的服务器用ApacheFTPServer

3.2 启动FTPS服务
package apache.ftp.server.test;

import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.PasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FtpServerApplication {
    public static void main(String[] args) throws Exception {
        FtpServerFactory serverFactory = new FtpServerFactory();

        //choose any. We're telling the FTP-server where to read it's user list
        PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
        //本地用于保存用户信息的文件,运行前创建准备好
        userManagerFactory.setFile(new File("E:\\FTPConfig\\users.properties"));
        userManagerFactory.setPasswordEncryptor(new PasswordEncryptor() {
            //We store clear-text passwords in this example
            @Override
            public String encrypt(String password) {
                //不加密
                return password;
            }

            @Override
            public boolean matches(String passwordToCheck, String storedPassword) {
                //直接比对
                return passwordToCheck.equals(storedPassword);
            }
        });

        UserManager um = userManagerFactory.createUserManager();

        //The user to save
        BaseUser user = new BaseUser();
        //设置用户名
        user.setName("admin");
        //设置密码
        user.setPassword("admin");
        //设置已存在的目录为该用户的主目录
        user.setHomeDirectory("E:\\FTP");
        //用户权限信息
        List<Authority> authorities = new ArrayList<Authority>();
        //添加写的权限
        authorities.add(new WritePermission());
        user.setAuthorities(authorities);

        //Save the user to the user list on the filesystem
        //保存用户
        um.save(user);
        serverFactory.setUserManager(um);

        ListenerFactory listenerFactory = new ListenerFactory();
        listenerFactory.setImplicitSsl(true);

        SslConfigurationFactory ssl = new SslConfigurationFactory();
        ssl.setKeystoreFile(new File("E:\\FTPConfig\\keyserver.keystore"));
        ssl.setKeystorePassword("123456");
        ssl.setTruststoreFile(new File("E:\\FTPConfig\\trustserver.keystore"));
        ssl.setTruststorePassword("123456");

        ssl.setClientAuthentication("true");
        listenerFactory.setSslConfiguration(ssl.createSslConfiguration());
        serverFactory.addListener("default", listenerFactory.createListener());

        //创建服务
        FtpServer server = serverFactory.createServer();
        //Your FTP server starts listening for incoming FTP-connections, using the configuration options previously set
        //最后一步
        server.start();
    }
}

代码比较简单,在正式项目中,只要参数配置化即可。

3.3 抓包测试

安装服务器证书。
在这里插入图片描述
在这里插入图片描述
连接FTPS,登录上传文件
在这里插入图片描述
在这里插入图片描述
FTP请求都是加密后的数据,在数据体中也是加密后的,完成 @_@…

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个 C# 的 FTPS 服务端,可以使用 .NET Framework 提供的 FtpListener 类来监听客户端连接请求和处理客户端的操作。 以下是一个简单的示例: ```csharp using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; class FtpsServer { private readonly TcpListener _listener; private readonly X509Certificate2 _certificate; private readonly bool _requireClientCertificate; public FtpsServer(IPAddress address, int port, X509Certificate2 certificate, bool requireClientCertificate) { _listener = new TcpListener(address, port); _certificate = certificate; _requireClientCertificate = requireClientCertificate; } public async Task StartAsync() { _listener.Start(); while (true) { TcpClient client = await _listener.AcceptTcpClientAsync(); await Task.Run(() => HandleClientAsync(client)); } } private async Task HandleClientAsync(TcpClient client) { SslStream sslStream = null; try { sslStream = new SslStream(client.GetStream(), false); await sslStream.AuthenticateAsServerAsync(_certificate, _requireClientCertificate, SslProtocols.Tls12, false); // 在此处处理客户端的 FTPS 请求和操作 } catch (AuthenticationException e) { Console.WriteLine($"Authentication failed: {e.Message}"); } catch (IOException e) { Console.WriteLine($"I/O error: {e.Message}"); } finally { sslStream?.Dispose(); client.Dispose(); } } } ``` 在 HandleClientAsync 方法中,可以使用 sslStream 对象来读取客户端发送的 FTPS 命令和数据,发送响应数据。 需要注意的是,客户端连接成功后,需要进行 SSL/TLS 握手协商,会话密钥的协商需要使用证书。如果客户端在连接时没有提供证书,可以通过设置 requireClientCertificate 参数为 false,来允许匿名连接。 示例代码中的 X509Certificate2 对象可以通过以下方式创建: ```csharp X509Certificate2 certificate = new X509Certificate2("mycert.pfx", "password"); ``` 其中,mycert.pfx 是证书文件的路径,password 是证书文件的密码。 以上是一个简单的实现,实际情况中还需要考虑更多细节,如用户认证、文件传输等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值