java - Java 如何接受我的自签名证书而无需将其添加到 Java 信任库

标签 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

)

最佳答案

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

查看 latest implementation of FTPSClient in the trunk of the Subversion repository ,它显然使用了 TrustManager 默认情况下来自 TrustManagerUtils.getValidateServerCertificateTrustManager() 的实现。

反过来,latest implementation of TrustManagerUtils显示这提供了一个 TrustManager,它只调用此证书上的 checkValidity(这是打开验证的选项,甚至不是 ACCEPT_ALL 实现) .不幸的是,checkValidity 仅检查证书在当前时间是否有效,关于其“不早于”和“不晚于”的有效期。它不是针对任何已知信任 anchor 的证书验证。这基本上几乎是无用的,因为能够插入不正确证书的攻击者应该能够创建一个具有他们想要的有效期的证书。

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

我还没有检查其余的实现,但我也想看看它对主机名 validator 做了什么,以防万一。

(可能值得在 Apache Commons Net 项目上报告这一点。这种默认行为当时可能听起来是个好主意,但事实并非如此。)

关于java - Java 如何接受我的自签名证书而无需将其添加到 Java 信任库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33675381/

相关文章:

java - 是否有 -noverify jvm 标志的替代方案?

java - ORMLite deleteDatabase 没有删除我的数据库

javascript - Restangular POST 失败 https ://OPTIONS pass

javascript - 从 JSON 数据将 CSV 文件上传到 S3 存储桶

c# - 使用 Amazon SQS 的 .net 应用程序示例

python - SparkContext 错误 - 找不到文件/tmp/spark-events 不存在

java - 如何将 README.md 复制到 src/main/resources 中?

java - 在 ConcurrentHashMap.computeIfPresent 中执行 `remappingFunction`

java - 连接到 Azure 中内置的 sonarqube 服务器时出错,未经验证的主机无法找到证书路径

ssl - 带有 SSL 加密的私有(private) Docker 注册表前端