«Удаленный сертификат недействителен в соответствии с процедурой проверки». используя SMTP-сервер Gmail - PullRequest
191 голосов
/ 22 апреля 2009

Я получаю эту ошибку:

Удаленный сертификат недействителен в соответствии с процедурой проверки.

всякий раз, когда я пытаюсь отправить электронную почту, используя SMTP-сервер Gmail в своем коде C # Может кто-нибудь указать мне правильное направление для решения этой проблемы?

Ниже приведена трассировка стека ...

at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Mail.SmtpConnection.Flush()
at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port)
at System.Net.Mail.SmtpTransport.GetConnection(String host, Int32 port)
at System.Net.Mail.SmtpClient.GetConnection()
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at BulkEmail.frmemail.mailsending(String toaddress, String fromaddress, String fromname, String subject, String pwd, String attachements, String mailmessage, String htmlmessage, Int32 i, Int32 j, String replytoaddress)

Ответы [ 19 ]

289 голосов
/ 07 сентября 2009

Предупреждение: не используйте это в рабочем коде!

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

Вызовите этот метод перед вызовом smtpclient.Send():

    [Obsolete("Do not use this in Production code!!!",true)]
    static void NEVER_EAT_POISON_Disable_CertificateValidation()
    {
        // Disabling certificate validation can expose you to a man-in-the-middle attack
        // which may allow your encrypted message to be read by an attacker
        // https://stackoverflow.com/a/14907718/740639
        ServicePointManager.ServerCertificateValidationCallback =
            delegate (
                object s,
                X509Certificate certificate,
                X509Chain chain,
                SslPolicyErrors sslPolicyErrors
            ) {
                return true;
            };
    }
49 голосов
/ 26 июля 2013

Ссылка здесь решила мою проблему.

http://brainof -dave.blogspot.com.au / 2008/08 / дистанционный сертификат является недействительным,-according.html

Я зашел на URL веб-службы (на сервере, на котором возникла проблема), щелкнул по маленькому значку безопасности в IE, который вызвал сертификат. Затем я нажал на вкладку «Подробности», нажал кнопку «Копировать в файл», что позволило мне экспортировать сертификат в виде файла .cer. Получив сертификат локально, я смог импортировать его в хранилище сертификатов на сервере, используя приведенные ниже инструкции.

Начать новую MMC. Файл -> Добавить / Удалить оснастку ... Нажмите Добавить ... Выберите Сертификаты и нажмите Добавить. Проверьте переключатель «Учетная запись компьютера». Нажмите Далее.

Выберите клиентский компьютер на следующем экране. Нажмите Готово. Нажмите Закрыть. Нажмите ОК. СЕЙЧАС установите сертификат в хранилище сертификатов доверенных корневых центров сертификации. Это позволит всем пользователям доверять сертификату.

37 голосов
/ 31 октября 2011

Вы можете улучшить код, спросив пользователя, когда сертификат недействителен, хочет ли он продолжить или нет. Хотите продолжить? Как показано ниже:

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;
    }
}
26 голосов
/ 15 октября 2014

Немного опоздал на вечеринку, но если вы ищете решение, подобное Юрию, следующий код поможет вам определить, связана ли проблема с самозаверяющим сертификатом и, если это так, игнорировать ошибку самозаверяющего. Вы можете явно проверить другие ошибки SSL, если хотите.

Код, который мы используем (любезно предоставлено Microsoft - http://msdn.microsoft.com/en-us/library/office/dd633677(v=exchg.80).aspx) выглядит следующим образом:

  private static bool CertificateValidationCallBack(
         object sender,
         System.Security.Cryptography.X509Certificates.X509Certificate certificate,
         System.Security.Cryptography.X509Certificates.X509Chain chain,
         System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
  // If the certificate is a valid, signed certificate, return true.
  if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
  {
    return true;
  }

  // If there are errors in the certificate chain, look at each error to determine the cause.
  if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
  {
    if (chain != null && chain.ChainStatus != null)
    {
      foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
      {
        if ((certificate.Subject == certificate.Issuer) &&
           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
        {
          // Self-signed certificates with an untrusted root are valid. 
          continue;
        }
        else
        {
          if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
          {
            // If there are any other errors in the certificate chain, the certificate is invalid,
         // so the method returns false.
            return false;
          }
        }
      }
    }

    // When processing reaches this line, the only errors in the certificate chain are 
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
    return true;
  }
  else
  {
 // In all other cases, return false.
    return false;
  }
}
15 голосов
/ 28 февраля 2016

У меня была точно такая же проблема, и я обнаружил, что по умолчанию Mail Shield от антивируса Avast имеет «Сканировать SSL-соединение» . Обязательно отключите это .

Насколько мне известно, Avast "откроет" почту, проверит ее на наличие вирусов и затем подпишет ее, используя собственный сертификат , чтобы почта не была подписана сертификат gmail, который выдает эту ошибку.

Решение 1:

  • Отключите сканирование SSL с вашего антивируса (или всего почтового экрана).

Решение 2 (Должно быть, если говорить о безопасности лучше):

  • Получите как-нибудь сертификат, используемый антивирусом (у Avast есть опция для его экспорта)
  • Импортируйте его в свой клиент imap / pop / smtp перед подключением к серверу gmail.
8 голосов
/ 18 декабря 2012

Вы уверены, что используете правильный адрес SMTP-сервера?

Оба smtp.google.com и smtp.gmail.com работают, но второй сертификат SSL выдан.

7 голосов
/ 31 мая 2013

Получите ту же ошибку при отправке из outlook из-за ssl. Попытка установки EnableSSL = false решила проблему.

пример:

var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",                   
                    Port = 587,
                    EnableSsl = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,                   
                    Credentials = new NetworkCredential("xxx@gmail.com", "xxxxx")
                };
7 голосов
/ 09 июля 2015

У меня была такая же ошибка, когда я пытался отправить электронную почту, используя SmtpClient через прокси-сервер (Usergate).

Проверяет, что сертификат содержит адрес сервера, который не равен адресу прокси-сервера, следовательно, ошибка. Мое решение: если при проверке сертификата возникает ошибка, получите сертификат, экспортируйте его и проверьте.

public static bool RemoteServerCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        // if got an cert auth error
        if (sslPolicyErrors != SslPolicyErrors.RemoteCertificateNameMismatch) return false;
        const string sertFileName = "smpthost.cer";

        // check if cert file exists
        if (File.Exists(sertFileName))
        {
            var actualCertificate = X509Certificate.CreateFromCertFile(sertFileName);
            return certificate.Equals(actualCertificate);
        }

        // export and check if cert not exists
        using (var file = File.Create(sertFileName))
        {
            var cert = certificate.Export(X509ContentType.Cert);
            file.Write(cert, 0, cert.Length);
        }
        var createdCertificate = X509Certificate.CreateFromCertFile(sertFileName);
        return certificate.Equals(createdCertificate);
    }

Полный код моего класса отправителя электронной почты:

public class EmailSender
{
    private readonly SmtpClient _smtpServer;
    private readonly MailAddress _fromAddress;

    public EmailSender()
    {
        ServicePointManager.ServerCertificateValidationCallback = RemoteServerCertificateValidationCallback;
        _smtpServer = new SmtpClient();
    }

    public EmailSender(string smtpHost, int smtpPort, bool enableSsl, string userName, string password, string fromEmail, string fromName) : this()
    {
        _smtpServer.Host = smtpHost;
        _smtpServer.Port = smtpPort;
        _smtpServer.UseDefaultCredentials = false;
        _smtpServer.EnableSsl = enableSsl;
        _smtpServer.Credentials = new NetworkCredential(userName, password);

        _fromAddress = new MailAddress(fromEmail, fromName);
    }

    public bool Send(string address, string mailSubject, string htmlMessageBody,
        string fileName = null)
    {
        return Send(new List<MailAddress> { new MailAddress(address) }, mailSubject, htmlMessageBody, fileName);
    }

    public bool Send(List<MailAddress> addressList, string mailSubject, string htmlMessageBody,
        string fileName = null)
    {
        var mailMessage = new MailMessage();
        try
        {
            if (_fromAddress != null)
                mailMessage.From = _fromAddress;

            foreach (var addr in addressList)
                mailMessage.To.Add(addr);

            mailMessage.SubjectEncoding = Encoding.UTF8;
            mailMessage.Subject = mailSubject;

            mailMessage.Body = htmlMessageBody;
            mailMessage.BodyEncoding = Encoding.UTF8;
            mailMessage.IsBodyHtml = true;

            if ((fileName != null) && (System.IO.File.Exists(fileName)))
            {
                var attach = new Attachment(fileName, MediaTypeNames.Application.Octet);
                attach.ContentDisposition.CreationDate = System.IO.File.GetCreationTime(fileName);
                attach.ContentDisposition.ModificationDate = System.IO.File.GetLastWriteTime(fileName);
                attach.ContentDisposition.ReadDate = System.IO.File.GetLastAccessTime(fileName);
                mailMessage.Attachments.Add(attach);
            }
            _smtpServer.Send(mailMessage);
        }
        catch (Exception e)
        {
            // TODO lor error
            return false;
        }
        return true;
    }

    public static bool RemoteServerCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;

    // if got an cert auth error
    if (sslPolicyErrors != SslPolicyErrors.RemoteCertificateNameMismatch) return false;
    const string sertFileName = "smpthost.cer";

    // check if cert file exists
    if (File.Exists(sertFileName))
    {
        var actualCertificate = X509Certificate.CreateFromCertFile(sertFileName);
        return certificate.Equals(actualCertificate);
    }

    // export and check if cert not exists
    using (var file = File.Create(sertFileName))
    {
        var cert = certificate.Export(X509ContentType.Cert);
        file.Write(cert, 0, cert.Length);
    }
    var createdCertificate = X509Certificate.CreateFromCertFile(sertFileName);
    return certificate.Equals(createdCertificate);
}

}

6 голосов
/ 12 августа 2015

Моя проблема была связана с Windows 2003 Server при вызове AuthenticateAsClient. Приведенные выше решения (например, обход ServicePointManager.ServerCertificateValidationCallback) не сработали.

Оказывается, это ошибка в Windows 2003, и есть исправление:

«Приложения, использующие API-интерфейс шифрования, не могут проверить сертификат X.509 в Windows Server 2003»

https://support.microsoft.com/en-us/kb/938397

Установка этого исправления решила мою проблему.

4 голосов
/ 10 февраля 2014

Проверьте дату и время вашего компьютера. Если это не так, обновите его до текущего времени или установите его автоматически, чтобы получить время из Интернета.

Поскольку сертификаты привязаны к фиксированному периоду времени, если ваши часы неверны, вы, скорее всего, получите такие ошибки. В этом случае, исправив время, проблема будет исправлена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...