SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection
Asked Answered
O

5

19

I'm trying to access gmail emails using imap and the code is failing at the ssl handshake without showing me any errors. Really appreciate if anyone could please help with this. I've built this using xunit, .NET Core 2.1. I'm using MailKit Nuget

   public GMailHandler(string mailServer, int port, bool ssl, string login, string password)

          //mailServer = imap.gmail.com
          //port = 993
          //ssl = true

          {

                  if (ssl)

                         Client.Connect(mailServer, port);

                  else

                         Client.Connect(mailServer, port);

                  Client.Authenticate(login, password);

                  Client.Inbox.Open(FolderAccess.ReadOnly);

          }
Oakley answered 25/11, 2019 at 6:28 Comment(2)
Does this answer your question? Access emails using imapRichers
Yohan: Please select the answer of @jstedfast, it is really a comprehensive answer and will help people to find the correct answer for all cases faster.Mescal
J
43

Here's a copy & paste from the MailKit FAQ:

Q: Why do I get "MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection." when I try to Connect?

When you get an exception with that error message, it usually means that you are encountering one of the following scenarios:

1. The mail server does not support SSL on the specified port.

There are 2 different ways to use SSL/TLS encryption with mail servers.

The first way is to enable SSL/TLS encryption immediately upon connecting to the SMTP, POP3 or IMAP server. This method requires an "SSL port" because the standard port defined for the protocol is meant for plain-text communication.

The second way is via a STARTTLS command (aka STLS for POP3) that is optionally supported by the server.

Below is a table of the protocols supported by MailKit and the standard plain-text ports (which either do not support any SSL/TLS encryption at all or only via the STARTTLS command extension) and the SSL ports which require SSL/TLS encryption immediately upon a successful connection to the remote host.

|Protocol|Standard Port|SSL Port|
|:------:|:-----------:|:------:|
| SMTP   | 25 or 587   | 465    |
| POP3   | 110         | 995    |
| IMAP   | 143         | 993    |

It is important to use the correct SecureSocketOptions for the port that you are connecting to.

If you are connecting to one of the standard ports above, you will need to use SecureSocketOptions.None, SecureSocketOptions.StartTls or SecureSocketOptions.StartTlsWhenAvailable.

If you are connecting to one of the SSL ports, you will need to use SecureSocketOptions.SslOnConnect.

You could also try using SecureSocketOptions.Auto which works by choosing the appropriate option to use by comparing the specified port to the ports in the above table.

2. The mail server that you are connecting to is using an expired (or otherwise untrusted) SSL certificate.

Often times, mail servers will use self-signed certificates instead of using a certificate that has been signed by a trusted Certificate Authority. Another potential pitfall is when locally installed anti-virus software replaces the certificate in order to scan web traffic for viruses.

When your system is unable to validate the mail server's certificate because it is not signed by a known and trusted Certificate Authority, the above error will occur.

You can work around this problem by supplying a custom RemoteCertificateValidationCallback and setting it on the client's ServerCertificateValidationCallback property.

In the simplest example, you could do something like this (although I would strongly recommend against it in production use):

using (var client = new SmtpClient ()) {
    client.ServerCertificateValidationCallback = (s,c,h,e) => true;

    client.Connect (hostName, port, SecureSocketOptions.Auto);

    // ...
}

Most likely you'll want to instead compare the certificate's Thumbprint property to a known value that you have verified at a prior date.

You could also use this callback to prompt the user (much like you have probably seen web browsers do) as to whether or not the certificate should be trusted.

3. A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.

Most Certificate Authorities are probably pretty good at keeping their CRL and/or OCSP servers up 24/7, but occasionally they do go down or are otherwise unreachable due to other network problems between you and the server. When this happens, it becomes impossible to check the revocation status of one or more of the certificates in the chain.

To ignore revocation checks, you can set the CheckCertificateRevocation property of the IMAP, POP3 or SMTP client to false before you connect:

using (var client = new SmtpClient ()) {
    client.CheckCertificateRevocation = false;

    client.Connect (hostName, port, SecureSocketOptions.Auto);

    // ...
}

4. The server does not support the same set of SSL/TLS protocols that the client is configured to use.

MailKit attempts to keep up with the latest security recommendations and so is continuously removing older SSL and TLS protocols that are no longer considered secure from the default configuration. This often means that MailKit's SMTP, POP3 and IMAP clients will fail to connect to servers that are still using older SSL and TLS protocols. Currently, the SSL and TLS protocols that are not supported by default are: SSL v2.0, SSL v3.0, and TLS v1.0.

You can override MailKit's default set of supported SSL and TLS protocols by setting the value of the SslProtocols property on your SMTP, POP3 or IMAP client.

For example:

using (var client = new SmtpClient ()) {
    // Allow SSLv3.0 and all versions of TLS
    client.SslProtocols = SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;

    client.Connect ("smtp.gmail.com", 465, true);

    // ...
}
Juanjuana answered 25/11, 2019 at 20:50 Comment(2)
The line client.CheckCertificateRevocation = false; worked for meChongchoo
Very comprehensive answer.Mescal
B
5

Disbaled Avast antivorus software . This works for me

Ballinger answered 29/3, 2021 at 7:32 Comment(0)
M
1

await client.ConnectAsync(_emailConfig.SmtpServer, _emailConfig.Port, false);

just set the "useSsl" option to false in the client configuration

Malagasy answered 23/11, 2020 at 19:15 Comment(2)
This is how I was doing it originally, and it worked fine for about a year and then all of the sudden stopped working with a hostname does not match error. (the certificate on the sever did not change) After switching to the method using SecureSocketOptions.None it worked fine againAblation
Not recommended. If doing so, anyone using the same wireless connection as you, the same network as you, watching traffic at your ISP, or anyone in a position to see your Internet traffic can read the information you send, including your login and password when you connect to your email address.Tyrolienne
R
0

I solved a similar problem by going through the protocols. As a result, I found out that the MS Exchange server uses Tls 1.0 for backward compatibility. I explicitly set the protocol and the connection passed.

var client = new ImapClient();
client.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
client.Connect("servername", 993, SecureSocketOptions.SslOnConnect);
Riproaring answered 1/6, 2022 at 8:47 Comment(0)
L
0

This issue might occur if you're trying to work with mail from a network with restrictive firewall settings, such as in an office environment.

To resolve this, try connecting via a different network.

Lenard answered 8/5 at 7:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.