Mailkit IMapClient 未命中 ServerCertificateValidationCallback 和 SslHandshakeException

问题描述

我正在尝试在 Windows Server 2019 机器上使用以下代码连接到 IMAP 服务器:

using (var client = new ImapClient(new ProtocolLogger("protocol.log")))
 {
        var address = EnvReader.GetStringValue("EMAIL_ADDRESS");
        var password = EnvReader.GetStringValue("EMAIL_PASSWORD");
        var creds = new NetworkCredential(address,password);

        client.CheckCertificateRevocation = false;
        client.ServerCertificateValidationCallback = (s,c,h,e) =>
        {
          Console.WriteLine("ALL UP IN THIS CALLBACK" + e.ToString());
          return true;
        };
        client.Connect("outlook.office365.com",993,SecureSocketoptions.SslOnConnect);
        client.Authenticate(address,password);
 }

在我的 Mac 上,此代码运行良好,我可以连接并随后进行身份验证。

在 Windows 机器上,我收到以下异常:

MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.
This usually means that the SSL certificate presented by the server is not trusted by the system for one or more of
the following reasons:
1. The server is using a self-signed certificate which cannot be verified.
2. The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
3. A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.
4. The certificate presented by the server is expired or invalid.
5. The set of SSL/TLS protocols supported by the client and server do not match.
6. You are trying to connect to a port which does not support SSL/TLS.

See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#SslHandshakeException for possible solutions

根据链接的 FAQ 中的信息,我添加了 ServerCertificateValidationCallback,但是从未命中回调(仍然抛出前面提到的异常,相关的控制台日志从未发生,并且在调试时从未命中回调中的断点).

根据我的阅读,ServerCertificateValidationCallback 应该处理异常消息提到的情况 #1-4。我可以在 Mac 上的指定端口上连接这一事实似乎排除了情况 #6(我也尝试了端口 143 + SecureSocketoptions.StartTls)。剩下案例 #5,但是,我找不到任何信息表明 Windows Server 2019 无法处理 SSL/TSL 协议。

对于 a) 处理此异常和/或 b) 找出 ServerCertificateValidationCallback 未触发的原因的任何想法将不胜感激。

编辑:我的项目引用了 .NET 5.0

解决方法

让我们来看看每一种可能性:

  1. 服务器正在使用无法验证的自签名证书。

outlook.office365.com 不会使用自签名证书,因此在这种情况下不会有问题。

  1. 本地系统缺少验证服务器证书所需的根证书或中间证书。

这个很有可能,但是 ServerCertificateValidationCallback 覆盖应该覆盖这个失败。然而,它并没有被击中……所以它实际上并没有绕过这个潜在的错误。

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

这将被 client.CheckCertificateRevocation = false; 否定

  1. 服务器提供的证书已过期或无效。

事实并非如此,因为证书要到 2022 年 1 月 21 日才会过期。

  1. 客户端和服务器支持的 SSL/TLS 协议集不匹配。

服务器至少支持 TLSv1.2,这是 MailKit 在所有目标框架版本(.NET 4.5 -> 5.0 + netstandard2.x's)中支持的默认 TLS 协议版本。

  1. 您正在尝试连接到不支持 SSL/TLS 的端口。

端口 993 是正确的端口,而 SslOnConnect 是正确的选项,所以这不是问题。

假设 MailKit 的 SslStream.AuthenticateAsClientAsync() 调用中没有错误传入验证回调方法(.NET 5.0 与其他版本不同),那么 InnerException 是什么?也许这会提供一些见解。