我在aws ec2实例上设置了一个FTPS服务器,并使用vsftpd配置了SSL。我使用-创建了SSL证书
sudo openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
我使用Apache Commons网络连接到我的FTPS服务器,并使用-检索文件
ftps = new FTPSClient(ftpsProtocol, isImplicit);
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.");
}
}
catch (IOException e)
{
if (ftps.isConnected())
{
try
{
ftps.disconnect();
}
catch (IOException f)
{
System.out.println("ERROR!");
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
__main:
try
{
ftps.enterLocalPassiveMode();
ftps.setBufferSize(1000);
ftps.execPROT("P");
if (!ftps.login(username, password))
{
ftps.logout();
error = true;
break __main;
}
}
这很好,我能够检索文件。既然它不是CA证书,Java如何在不抛出错误的情况下接受服务器的自签名证书?
(我的vsftpd conf有以下几行-我的vsftpd.conf有以下行-
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
pasv_enable=YES
pasv_max_port=12100
pasv_min_port=12000
port_enable=YES
)
您没有显示如何初始化FTPSClient
,但我假设您使用了默认值。
看看Subversion存储库主干中FTPSClient
的最新实现,它明显使用了默认情况下来自TrustManagerUtils.getValidateServerCertificateTrustManager()
的TrustManager
实现。
反过来,TrustManagerUtils
的最新实现表明,它提供了一个仅在此证书上调用checkValidity
的TrustManager
(这是启用验证的选项,甚至不是ACCEPT_ALL
实现)。不幸的是,checkValidity
只检查证书在当前时间的"不在此之前"one_answers"不在此之后"的有效日期是否有效。这不是针对任何已知的信任锚来验证证书。这基本上是非常无用的,因为攻击者能够插入不正确的证书,应该能够创建一个具有他们想要的有效日期的证书。
然而,您似乎可以用SSLContext
实例化FTPSClient
,因此使用new FTPSClient(SSLContext.getDefault())
将为您提供默认的、更明智的行为(除非您更改了默认的SSLContext
)。(当然,您也可以使用具有正确行为的自定义SSLContext
,但也可以使用特定的信任库进行初始化。)
我还没有检查其余的实现,但我也会看看它对主机名验证器的作用,以防万一。
(可能值得在Apache Commons Net项目中报告这一点。这种默认行为在当时听起来可能是个好主意,但事实并非如此。)