Java如何在不必将其添加到Java信任库的情况下接受我的自签名证书

时间:2015-11-12 15:41:32

标签: java ssl amazon-ec2 apache-commons-net ftps

我在我的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 net连接到我的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

1 个答案:

答案 0 :(得分:2)

您没有展示自己如何初始化FTPSClient,但我假设您已使用默认值。

查看latest implementation of FTPSClient in the trunk of the Subversion repository,默认情况下使用来自TrustManager的{​​{1}}实施明显。

反过来,latest implementation of TrustManagerUtils显示这提供TrustManagerUtils.getValidateServerCertificateTrustManager()仅在此证书上调用TrustManager(并且启用了验证的选项,甚至是checkValidity实施)。不幸的是,ACCEPT_ALL仅检查证书在当前时间是否有效,而不是在"之前。 "而不是"有效期。它不是针对任何已知信任锚的证书验证。这基本上非常接近无用,因为有能力插入错误证书的攻击者应该能够创建一个具有所需有效日期的证书。

但是,您似乎可以使用checkValidity实例化FTPSClient,因此使用SSLContext会为您提供默认的,更明智的行为(除非您更改了默认值new FTPSClient(SSLContext.getDefault()))。 (当然,您也可以使用具有正确行为的自定义SSLContext,但也使用特定的信任库进行初始化。)

我还没有检查其余的实现,但我会看看它对主机名验证器的作用,以防万一。

(它可能值得在Apache Commons Net项目上报告这个。这种默认行为在当时可能听起来不错,但它确实不是。)