Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FtpWebRequest "The remote certificate is invalid according to the validation procedure"

I have a .NET client application that tries to ftp over a file to an FTP site which has a self-signed TLS/SSL certificate. This FTP site is running on Windows 7 Enterprise, IIS 7. I am getting the following error:

The remote certificate is invalid according to the validation procedure

I have tried installing the certificate in the trusted root certificates but that still does not work.

I have used the delegate call back in the code that is mentioned some of the posts here - it works. But I do not want to use that in my production code.

Also in production some of our customers are using self-signed certificates.

Any ideas on how to fix this issue?

like image 226
John Smith Avatar asked Jul 20 '12 20:07

John Smith


2 Answers

The most voted answer by @Luca blindly accepts any certificate. That's a security flaw.

When implementing ServicePointManager.ServerCertificateValidation callback one should validate the certificate. E.g. by checking certificate's hash against a known value:

using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, certificate, chain, errors) =>
    {
        return
            (errors == SslPolicyErrors.None) ||
            certificate.GetCertHashString(HashAlgorithmName.SHA256).Equals(
                "EB8E0B28AE064ED58CBED9DAEB46CFEB3BD7ECA677...");
    };

For the X509Certificate.GetCertHashString overload that takes HashAlgorithmName.SHA256, you need .NET 4.8. On older versions use the parameter-less overload that returns an SHA-1 hash.


Based on Is it safe to test the X509Certificate.Thumbprint property when you know an invalid certificate is safe?

For VB.NET version of the code, see Accept self-signed TLS/SSL certificate in VB.NET.

like image 81
Martin Prikryl Avatar answered Sep 29 '22 08:09

Martin Prikryl


You have to overwrite the certificate checks so that they will always be considered good. That won't prevent the channel to remain SSL protected.

Uri target = new Uri("ftp://yourUri");
string fileName = @"fullPathOfYourFile";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("user", "password");
request.EnableSsl = true;

//overwrite the certificate checks
ServicePointManager.ServerCertificateValidationCallback = 
                      (s, certificate, chain, sslPolicyErrors) => true;

// Copy the contents of the file to the request stream
//....
like image 20
Luca Quaglia Avatar answered Sep 29 '22 09:09

Luca Quaglia