9

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?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
John Smith
  • 91
  • 1
  • 1
  • 3

4 Answers4

10

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
//....
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Luca Quaglia
  • 109
  • 1
  • 3
  • 3
    While this "works", it's not secure. You should verify the certificate, not blindly accept any. For a way to validate the certificate, see [my answer](https://stackoverflow.com/q/11586206/850848#66776112). – Martin Prikryl Mar 24 '21 at 07:01
10

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.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
1

You also get this error if you try to connect to IP address instead of domain name. Since certificate is issued to the domain name, IP address wont work.

Ergec
  • 11,608
  • 7
  • 52
  • 62
0

I had the same issue via .NET and the certificate root and chain was trusted by my account and even the local machine account. So the cert was golden.

For me, I was using the wrong hostname. I was using a fully qualified name (and was getting to the correct place), but the cert was actually issued to a different alias. So make sure your server name matches exactly what's on the certificate.

Check this article, that's how I found the answer... Maybe the event subscription is what you need too...

http://www.limilabs.com/blog/the-remote-certificate-is-invalid-according-to-the-validation-procedure

Matt
  • 325
  • 3
  • 5
  • 2
    It turned out I had a similar problem. The FtpWebRequest was using an IP address ("1.2.3.4") and of course the cert was a wildcard one issued to the domain name ("*.example.com"). Once I switched to using the domain name in my FtpWebSession this error went away. – Rich May 13 '15 at 15:04