SslHandshakeException:尝试建立 SSL 或 TLS 连接时出错

Yoh*_*ake 7 c# ssl imap xunit mailkit

我正在尝试使用 imap 访问 gmail 电子邮件,并且代码在 ssl 握手时失败,但没有显示任何错误。如果有人可以帮忙解决这个问题,真的很感激。我已经使用 xunit,.NET Core 2.1 构建了它。我正在使用 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);

          }
Run Code Online (Sandbox Code Playgroud)

jst*_*ast 13

这是MailKit 常见问题解答中的复制和粘贴:

问:为什么"MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection."我尝试连接时会出现?

当您收到带有该错误消息的异常时,通常意味着您遇到了以下情况之一:

1. 邮件服务器不支持指定端口上的 SSL。

有两种不同的方法可以将 SSL/TLS 加密用于邮件服务器。

第一种方法是在连接到 SMTP、POP3 或 IMAP 服务器后立即启用 SSL/TLS 加密。此方法需要“SSL 端口”,因为为协议定义的标准端口用于纯文本通信。

第二种方法是通过 服务器可选支持的STARTTLS命令(也称为STLSPOP3)。

下表是 MailKit 支持的协议和标准纯文本端口(根本不支持任何 SSL/TLS 加密或仅通过STARTTLS 命令扩展支持)和需要 SSL/TLS 加密的 SSL 端口。成功连接到远程主机。

|Protocol|Standard Port|SSL Port|
|:------:|:-----------:|:------:|
| SMTP   | 25 or 587   | 465    |
| POP3   | 110         | 995    |
| IMAP   | 143         | 993    |
Run Code Online (Sandbox Code Playgroud)

SecureSocketOptions对要连接的端口使用正确的端口很重要。

如果您要连接到上述标准端口之一,则需要使用SecureSocketOptions.None, SecureSocketOptions.StartTlsSecureSocketOptions.StartTlsWhenAvailable

如果要连接到 SSL 端口之一,则需要使用SecureSocketOptions.SslOnConnect.

您也可以尝试SecureSocketOptions.Auto通过选择适当的选项来使用哪种工作,通过将指定的端口与上表中的端口进行比较来选择使用。

2. 您要连接的邮件服务器正在使用过期(或不受信任)的 SSL 证书。

通常,邮件服务器将使用自签名证书,而不是使用由受信任的证书颁发机构签名的证书。另一个潜在的陷阱是本地安装的防病毒软件会替换证书以扫描网络流量中的病毒。

当您的系统无法验证邮件服务器的证书,因为它不是由已知且受信任的证书颁发机构签名时,就会出现上述错误。

您可以通过提供自定义RemoteCertificateValidationCallback 并将其设置在客户端的ServerCertificateValidationCallback 属性上来解决此问题。

在最简单的例子中,你可以做这样的事情(虽然我强烈建议不要在生产中使用它):

|Protocol|Standard Port|SSL Port|
|:------:|:-----------:|:------:|
| SMTP   | 25 or 587   | 465    |
| POP3   | 110         | 995    |
| IMAP   | 143         | 993    |
Run Code Online (Sandbox Code Playgroud)

您很可能希望将证书的Thumbprint 属性与您在先前日期验证的已知值进行比较。

您还可以使用此回调来提示用户(很像您可能在 Web 浏览器中看到的那样)是否应该信任证书。

3. 链中一个或多个证书的证书颁发机构 CRL 服务器暂时不可用。

大多数证书颁发机构可能非常擅长保持其 CRL 和/或 OCSP 服务器 24/7 全天候运行,但有时它们确实会出现故障或由于您和服务器之间的其他网络问题而无法访问。发生这种情况时,就无法检查链中一个或多个证书的吊销状态。

要忽略吊销检查,您可以在连接之前将 IMAP、POP3 或 SMTP 客户端的CheckCertificateRevocation属性设置为 false

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

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

4. 服务器不支持客户端配置使用的同一组 SSL/TLS 协议。

MailKit 试图跟上最新的安全建议,因此不断从默认配置中删除不再被视为安全的旧 SSL 和 TLS 协议。这通常意味着 MailKit 的 SMTP、POP3 和 IMAP 客户端将无法连接到仍在使用旧 SSL 和 TLS 协议的服务器。目前,默认不支持的 SSL 和 TLS 协议有:SSL v2.0、SSL v3.0 和 TLS v1.0。

您可以 通过 在 SMTP、POP3 或 IMAP 客户端上设置SslProtocols属性的值来覆盖 MailKit 的默认支持SSL 和 TLS 协议集 。

例如:

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

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • “client.CheckCertificateReplication = false;”行对我有用 (3认同)