0

我正在使用 C# 控制台应用程序来重现该问题。这是一个.NET Framework 4.7应用程序。FluentFTP版本是 24.0.0,作为 Nuget 包安装。

这是我的代码:

using FluentFTP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace FTP_Test
{
    class Program
    {
        private static string host = "<my host>";
        private static string username = "<my username>";
        private static string pass = "<my pass>";
        private static int port = 990;

        static void Main(string[] args)
        {
            FtpClient ftpClient = new FtpClient(host, port, username, pass);

            ftpClient.DataConnectionType = FtpDataConnectionType.EPSV;
            ftpClient.EncryptionMode = FtpEncryptionMode.Implicit;

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

                        ftpClient.DataConnectionEncryption = true;
            ftpClient.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
            var cer = new System.Security.Cryptography.X509Certificates.X509Certificate2();
            ftpClient.ClientCertificates.Add(cer);
            ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback;

            ftpClient.Connect();
        }

        private static void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
        {
            // add logic to test if certificate is valid here
            e.Accept = true;
        }
        private static bool ServerCertificateValidationCallback(object sender,
                                                System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                                System.Security.Cryptography.X509Certificates.X509Chain chain,
                                                System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}

我在控制台中遇到的错误(和堆栈跟踪):

Unhandled Exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at FluentFTP.FtpSocketStream.ActivateEncryption(String targethost, X509CertificateCollection clientCerts, SslProtocols sslProtocols)
   at FluentFTP.FtpClient.Connect()
   at FTP_Test.Program.Main(String[] args) in C:\Users\Nemanja\source\repos\FTP Test\Program.cs:line 35

我在这里想念什么?

我可以使用同一组主机/用户/密码通过 Filezilla 进行连接。在 Filezilla 中,我必须设置以下内容:

  • 加密:需要基于 TLS 的隐式 FTP(在“常规”选项卡中)
  • 传输模式:被动(在“传输设置”选项卡中)

当我在调试模式下运行应用程序并在函数 OnValidateCertificate 和 ServerCertificateValidationCallback 中设置断点时,不会命中这些断点。

4

1 回答 1

0

原来 FluentFTP 不支持隐式 SSL,所以我不得不切换到 Chilkat。

example-code.com 对此库有很好的示例,这里是隐式 SSL 示例的链接: https ://www.example-code.com/csharp/ftp_implicitSSL.asp

如果链接停止工作,请在此处复制示例(来自上面的链接)。

// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

Chilkat.Ftp2 ftp = new Chilkat.Ftp2();

// If this example does not work, try using passive mode
// by setting this to true.
ftp.Passive = false;
ftp.Hostname = "ftp.something.com";
ftp.Username = "test";
ftp.Password = "test";
ftp.Port = 990;

// We don't want AUTH SSL:
ftp.AuthTls = false;

// We want Implicit SSL:
ftp.Ssl = true;

// Connect and login to the FTP server.
bool success = ftp.Connect();
if (success != true) {
    Debug.WriteLine(ftp.LastErrorText);
    return;
}
else {
    // LastErrorText contains information even when
    // successful. This allows you to visually verify
    // that the secure connection actually occurred.
    Debug.WriteLine(ftp.LastErrorText);
}

Debug.WriteLine("FTPS Channel Established!");

// Do whatever you're doing to do ...
// upload files, download files, etc...

success = ftp.Disconnect();
于 2022-02-02T11:37:45.587 回答