Получение «Удаленный сертификат недействителен в соответствии с процедурой проверки», когда SMPT-сервер имеет действительный сертификат

Это кажется распространенной ошибкой, но, хотя я нашел обходной путь (см. Ниже), я не могу точно определить причину, по которой я его получаю.

Я записываю функциональность SMTP в наше приложение и пытаюсь добавить функциональность SSL к уже работающему SMTP.

Я тестирую на сервере MS Exchange нашей компании и, в частности, на нем включена опция веб-почты. Я могу отправлять электронные письма внутренне с помощью своего кода, не аутентифицируя свое соединение и отправляя анонимно, однако эти электронные письма не будут передаваться на внешние адреса электронной почты из-за политики наших компаний. Помимо того, что я программирую это для наших клиентов, и они не все допускают открытое реле и / или анонимные соединения.

Я считаю, что сервер Exchange использует явный SSL / TLS. Я попробовал telnet к адресу сервера на порту 25 и получил текстовый ответ, понятный человеку, который, согласно некоторым из моих предыдущих поисков, означает, что он использует явный SSL / TLS.

У меня есть следующий тестовый код

SmtpClient SMTPClient = new SmtpClient(webmailaddress);
SMTPClient.Port = 25;
SMTPClient.UseDefaultCredentials = true;
SMTPClient.EnableSsl = true;
System.Net.Mail.MailMessage Message = new `
System.Net.Mail.MailMessage(emailFrom,emailTo,subject,body);
SMTPClient.Send(Message);

Во время поиска решения я столкнулся с этим«Удаленный сертификат недействителен в соответствии с процедурой проверки». используя SMTP-сервер Gmail

Из которого я получил следующий код ...

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

public static bool ValidateServerCertificate(object sender,X509Certificate certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;
    else
    {
        if (System.Windows.Forms.MessageBox.Show("The server certificate is not valid.\nAccept?", "Certificate Validation", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            return true;
        else
            return false;
    }
}

Это работает в моем тестовом коде. ОДНАКО фактический процесс, который я пишу (а не мой тестовый код) будет выполняться в фоновом режиме и не сможет спросить пользователя (вместо этого он сообщает об ошибках в журнале ошибок Windows).

Когда я начал, мой вопрос действительно, почему я вообще получаю эту ошибку. Если я захожу на https: webmail.ourdomain.co.uk в браузере, он показывает действительный сертификат, и нет никакой возможности установить сертификат (как я сделал бы, если бы он был самоподписанным).

 Тем не менее, когда я запускаю свой код с указанием прерывания отладки в методе ValidateServerCertificate, я смотрю на значения сертификата и вижу издателя нашего локального сервера и свойства «не использовать до» и «не использовать после» сегодня. Это не соответствует сертификату, который я получаю.

Я также проверил, что есть флаги sslPolicyErrors в отладке ValidateServerCertificate, и они показывают «RemoteCertificateChainErrors» и «RemoteCertificateNameMismatch».

Так что мне не хватает в этом ... почему он не использует правильный сертификат? Если есть какие-то шаги, которые мне нужно предпринять, чтобы установить сертификат локально, чтобы использовать его, тогда мне нужно знать их, чтобы я мог сказать своим клиентам, что делать, если они получат это.

Я не хочу просто обойти проверку, возвращая true из метода ValidateServerCertificate, и поскольку это фоновый процесс, я не могу спросить пользователя, поэтому мне нужно понять, как заставить мой код использовать правильный / доверенный сертификат.

Надеюсь, кто-то может посоветовать.

Ответы на вопрос(3)

Ваш ответ на вопрос