Удаленный сертификат недействителен согласно процедуре проверки. с помощью SMTP-сервера Gmail

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

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

всякий раз, когда я пытаюсь отправить электронную почту с помощью 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)

person Josh    schedule 22.04.2009    source источник
comment
Не могли бы вы рассказать нам больше о своей конфигурации для использования SMTP-серверов Gmail? Моя удачная догадка: не могли бы вы рассказать нам больше о своей политике безопасности для SSL (например, об использовании действительного / недействительного SSL-сертификата?).   -  person Brian Clozel    schedule 27.04.2009
comment
Не могли бы вы дать нам образец кода, в котором можно воспроизвести ошибку?   -  person zaTricky    schedule 05.12.2017


Ответы (23)


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

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

Вызовите этот метод перед вызовом 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;
            };
    }
person Yury Skaletskiy    schedule 06.09.2009
comment
Это взлом, а не исправление? - person LB.; 07.04.2010
comment
Хотелось бы увидеть исправление, а не полностью отключать безопасность. - person Roman Starkov; 15.04.2011
comment
как обходной путь к проблеме безопасности вы можете отключить безопасность? Какого черта? - person John Nicholas; 06.07.2012
comment
Для меньшего набора текста (без использования операторов using) это та же строка кода: ServicePointManager.ServerCertificateValidationCallback = delegate (object s, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X50X509Certificates.X50X509Certificates. цепочка, System.Net.Security.SslPolicyErrors sslPolicyErrors) {return true; }; - person Clearly; 31.07.2012
comment
Эй, я использовал это решение, и обратный вызов никогда не запускается, есть подсказка, почему? - person guiomie; 13.08.2012
comment
Объяснение и исправление приведены в другом ответе. - person Rick Sladkey; 28.03.2013
comment
Это было приятно, потому что это позволило мне увидеть, что еще не так в моем коде, кроме безопасности; Теперь, когда я знаю, что все остальное в порядке, я могу работать над настройками безопасности. Удаление переменных полезно для отладки. - person caleb; 09.04.2013
comment
System.Net.ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, errors) = ›true; - person shawndumas; 14.05.2013
comment
Пришлось проголосовать против этого, поскольку люди все еще думают, что это решение. Это ПРОСТО ОТКЛЮЧАЕТ БЕЗОПАСНОСТЬ. НЕ ИСПОЛЬЗУЙТЕ В ПРОИЗВОДСТВЕ, народ. Он даже так говорит. Блин. - person MGOwen; 03.06.2013
comment
Проголосовали. Я полностью согласен, что это не должно использоваться в производстве НО .. Я делаю прототип чего-то. Тестовый сервер, который они мне предоставили, заставляет меня использовать SSL. Работа с сертификатами для меня довольно нова, поэтому я просто хочу БЫСТРЫЙ ПУТЬ, что, по-моему, нормально, поскольку Я НЕ БУДУ ИСПОЛЬЗОВАТЬ ЕГО В ПРОИЗВОДСТВЕ - person TweeZz; 26.03.2014
comment
Конечно, этот обходной путь в первую очередь лишает нас возможности иметь сертификат SSL? - person davidb; 10.04.2014
comment
Мне не нравятся комментарии к проблемам с SSL. Так когда же SSL будет протестирован? Я видел много проблем, связанных с SSL-коммуникациями и принудительным применением SSL каждый раз в средах DEV и заставляющих DEVS заставить его работать. Поначалу это может быть проблемой, но администраторы быстро разбираются со своими сертификатами и серверами. Устраняйте причину, а не симптом! Я не хочу, чтобы тест системной интеграции тестировал непроверенные соединения кода. Или плохо протестированные процессы. Такой код может быть забыт и попадет в прод ... и т. Д. Если я видел, как разработчик делает это, его ждет абсолютная трепка. - person phil soady; 13.08.2014
comment
Фактическое исправление см. В ответе T-Rex ниже, который включает в себя ручное доверие сертификату. - person DeepSpace101; 01.09.2014
comment
Что меня смущает, так это то, что поведение по умолчанию с самозаверяющими сертификатами заключается в отказе от связи, в то время как отсутствие шифрования (без SSL) не показывает пользователю никаких красных флажков. - person Zoey; 28.12.2014
comment
Неужто лучше в клиентском коде установить сертификат? - person Dave Arkell; 24.04.2015
comment
Немного короче в C # 6: ServicePointManager.ServerCertificateValidationCallback = (s, certificate, chain, sslPolicyErrors) = ›true; - person roeland; 23.11.2015
comment
Если вы используете Prod, у вас должен быть действующий сертификат, и вы не должны столкнуться с этой проблемой. Но я бы порекомендовал это исправление для сред, не связанных с производством, для использования с Appsetting, например IsTestMode = true. - person Dhanuka777; 12.02.2016
comment
В этом нет ничего плохого. Это может быть приложение, отправляющее электронное письмо через TLS-сервер в локальной сети. Сертификат может быть самоподписанным, то есть, по крайней мере, есть шифрование, которого обычно нет. И даже если он используется в обычном Интернете, шифрование по сравнению с шифрованием по-прежнему является допустимым аргументом, даже если нет проверки сертификата. - person Todd; 26.09.2016
comment
@Todd Если нет подтверждения сертификата, шифрование небезопасно. Его присутствие может потребовать от потенциального злоумышленника некоторых дополнительных шагов и может защитить от случайного раскрытия данных дружелюбным администраторам, но также может дать ложное ощущение безопасности. Если это внутреннее приложение, в котором вы не хотите возиться с официальным сертификатом, есть несколько других решений, например, заставить приложение доверять ЭТОМ конкретному сертификату вместо отключения проверки сертификата или создать частный ЦС, который вы устанавливаете как доверенный. соответствующий компьютер. - person Oskar Berggren; 13.10.2016
comment
Отличный ответ для моего тестового сценария! Если вы не умеете читать предупреждения или не знаете, что делает ваш код, вы, вероятно, не в той профессии ... - person user919426; 07.04.2017
comment
Полезно для модульного тестирования, когда вам нужно подделать дату и время, что затрудняет действительность сертификата. - person kravits88; 09.04.2017
comment
«Не использовать в производственной среде», как будто машины разработчиков каким-то образом невосприимчивы к MITM или GMail работает локально на вашем компьютере. - person Sedat Kapanoglu; 05.12.2017
comment
он содержит четыре параметра, поэтому вы можете использовать красивое четырехбуквенное слово, чтобы указать, что это плохо, например: ServicePointManager.ServerCertificateValidationCallback = (h,a,c,k) => true; или ServicePointManager.ServerCertificateValidationCallback = (f,u,c,k) => true; - person Marius; 26.06.2018
comment
это, безусловно, должно быть решением. Ваше приложение может использовать либо настройку конфигурации для переключения, либо просто проверить, содержит ли имя хоста localhost. - person ZZZ; 12.07.2018
comment
Согласитесь, что это взлом, но тогда он использует самозаверяющий сертификат. Я вставил этот код (завернутый в if (System.Diagnostics.Debugger.IsAttached), чтобы смягчить эффект попадания в prod, если меня ударит автобус, прежде чем его удалить), и СЛАВА БУДЬ! это означало, что я смог позвонить и убедиться, что все остальное работает правильно. Поэтому, несмотря на то, что у меня нет решения, которое будет безопасно работать в dev и prod, я все еще в лучшем положении, чем раньше. - person OutstandingBill; 23.07.2018
comment
Вау, спасибо :)) - person Fox; 08.02.2021

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

http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html

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

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

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

person T-Rex    schedule 26.07.2013
comment
+1 при импорте сертификата с помощью инструмента импорта на сертификате, а не через оснастку, это только для вашей учетной записи. Использование оснастки позволяет вам выбрать, для кого будет выполняться импорт: учетная запись пользователя, учетная запись службы или всех остальных. Спасибо за указатель. Я тут пару минут чесал затылок! - person davidb; 10.04.2014
comment
Если вы хотите использовать командную строку для автоматизации всех рабочих станций разработки / тестирования - certutil -f -p test -importPFX Root devcert.pfx и certutil -f -p test -importPFX MY devcert.pfx. Требуется запускать в командной строке администратора (при условии, что пароль PFX - test) - person DeepSpace101; 01.09.2014
comment
Это лучший способ исправить это, если вы используете самозаверяющий сертификат для тестирования, спасибо T-Rex! - person ToastyMallows; 30.10.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;
  }
}
person Hooligancat    schedule 15.10.2014
comment
В моем случае sslPolicyErrors был RemoteCertificateNameMismatch, и я изменил проверку сертификата, потому что у нас не было одинаковых значений Subject и Issuer. - person Ufuk Hacıoğulları; 27.09.2016
comment
X509Certificate, используемый сервером Exchange, продолжал переключаться между самозаверяющим и доверенным. Использование этого кода помогло моему сетевому администратору и мне не только понять, что это было так, но и полностью решить проблему, просто обойдя самозаверяющие сертификаты. Это было прекрасно! - person Bret; 24.03.2017

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

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;
    }
}
person LinuxLover    schedule 31.10.2011
comment
Кто нажмет кнопку «Продолжить», если это облачное приложение? - person Konstantin Isaev; 07.08.2013

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

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

Решение 1.

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

Решение 2 (с точки зрения безопасности):

  • Получите каким-либо образом сертификат, используемый антивирусом (у Avast есть возможность его экспортировать)
  • Импортируйте его в свой клиент imap / pop / smtp перед подключением к серверу gmail.
person tehCivilian    schedule 27.02.2016
comment
Вы сэкономили мне столько времени. Потребовалась бы целая вечность, чтобы понять, что виноват мой антивирус, а не мой код. - person arao6; 11.07.2016
comment
Благодарю за ваш ответ. Вы сэкономили мне столько времени. - person SoftwareDveloper; 04.03.2021

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

пример:

var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",                   
                    Port = 587,
                    EnableSsl = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,                   
                    Credentials = new NetworkCredential("[email protected]", "xxxxx")
                };
person Chitra Pannirselvam    schedule 30.05.2013
comment
gmail не позволит вам подключиться, пока вы устанавливаете SSL на false, я пробовал ваше решение, оно не сработало для меня. - person Zeeshan Ajmal; 28.11.2013
comment
Да, это то, что я называю базовым (по сравнению с отсутствием или ssl) ....... эти настройки электронной почты иногда бывают сложными. - person granadaCoder; 14.08.2015

Я знаю, что довольно поздно участвую в этой игре, но я не видел здесь ответа, указывающего на журналы system.diagnostics для потока TLS.

Прежде чем вносить какие-либо изменения в свой код, убедитесь, что вы понимаете, в чем проблема. AuthenticationException - одно из тех очень общих исключений, которые мало что говорят. Чтобы узнать, что происходит внутри, отредактируйте файл app.config для своего приложения (или создайте новый) и убедитесь, что в разделе system.diagnostics включен источник трассировки System.Net, например:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" />
    <sharedListeners>
      <add name="file" initializeData="c:\network.log" type="System.Diagnostics.TextWriterTraceListener" />
    </sharedListeners>
    <sources>
      <source name="System.Net" switchValue="Verbose">
        <listeners>
          <add name="file" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Перезапустите приложение и проверьте файл c: \ network.log. Вы должны увидеть там подробную информацию о вашем TLS (SSL) соединении, например:

System.Net Information: 0 : [12764] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = f44368:535f958, targetName = localhost, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [12764] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=OK).
System.Net Information: 0 : [12764] Remote certificate: [Version]
  V3

[Subject]
  CN=test
  Simple Name: test
  DNS Name: example.com

[Issuer]
  CN=Root CA
  Simple Name: Root CA
  DNS Name: Root CA

...

[Signature Algorithm]
  sha256RSA(1.2.840.113549.1.1.11)

[Public Key]
  Algorithm: RSA
  Length: 2048
  Key Blob: ....
System.Net Information: 0 : [12764] SecureChannel#38496415 - Remote certificate has errors:
System.Net Information: 0 : [12764] SecureChannel#38496415 -    Certificate name mismatch.
System.Net Information: 0 : [12764] SecureChannel#38496415 - Remote certificate was verified as invalid by the user.
System.Net Error: 0 : [12764] Exception in AppDomain#10923418::UnhandledExceptionHandler - The remote certificate is invalid according to the validation procedure..

Зная, что вызывает проблему, вы сможете решить ее или, по крайней мере, сузить область поиска в Google.

person Sebastian    schedule 05.10.2018

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

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

person Pawel Lesnikowski    schedule 17.12.2012

У меня была такая же ошибка, когда я пытался отправить электронное письмо с помощью 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);
}

}

person Evgeny Ivanov    schedule 09.07.2015

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

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

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

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

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

person user326608    schedule 12.08.2015

Моя проблема заключалась не в том, что я ссылался на сервер по IP-адресу, а не по URL-адресу. Я купил подписанный сертификат в ЦС для использования в частной сети. URL-адрес, указанный в сертификате, имеет значение при обращении к серверу. Как только я обратился к серверу по URL-адресу в сертификате, все начало работать.

person Josh    schedule 06.03.2014
comment
Этот ответ заслуживает того, чтобы быть выше, потому что он указывает на распространенную ошибку; люди (включая меня) думают, что цель Host - только найти сервер. - person Mojtaba; 21.02.2018

Папка вашего веб-сайта требует защиты сетевых служб. Особенно web.config. Он использует эту учетную запись для доступа к вашему реестру для получения сертификатов. Это избавит от необходимости добавлять взлом в ваш код.

person Frans    schedule 19.07.2012

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

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

person AliSafari186    schedule 10.02.2014
comment
Если системная дата слишком далека от текущего времени, действительность сертификата, полученного от Google, вызывает проблему. Он видит выданную и действительную информацию, которая не является текущим временем. Это не единственное, что не может вызвать эту проблему. Но он, безусловно, может. - person phil soady; 13.08.2014
comment
Чрезвычайно полезное напоминание, чтобы дважды проверить это в моем случае! Бритва Оккама и все такое ... :) Теперь об этой CMOS-батарее ... - person Mike G; 03.10.2017

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

Поэтому вам необходимо изменить URL-адрес поставщика на https://CertificateSubject/xxx/xxx.application.

person Ludwo    schedule 09.04.2015
comment
Вы можете это уточнить? В моем случае приложение работает на одном сервере и не работает на другом. Бестолку ... Я не специалист, но домен все еще подключен к рабочему, и сертификат сервера уже установлен на обеих машинах. До сих пор не понимаю, почему это может иметь какое-то значение, поскольку в нем говорится об удаленном сертификате. - person Michael Brennt; 01.09.2016

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

http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html

person NullPointer    schedule 05.11.2012

В блоге MSDN есть статья об исследовании этого типа проблем:

Устранение неполадок ASP.NET - удаленный сертификат недействителен в соответствии с процедурой проверки:
http://blogs.msdn.com/b/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is-invalid-согласно-the-validation-procedure.aspx

person David Burg    schedule 13.09.2013

Добавление этой строки сработало для меня. Фактически это доверяет всем сертификатам, упомянутым здесь . Однако это можно использовать в первую очередь для устранения неполадок. Если это работает для вас, это означает, что сертификат удаленного сервера не добавлен в качестве доверенного сертификата на вашем компьютере.

System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);

Полный код

private void sendAMail(String toAddress, String messageBody)
        {
            String msg = "Sending mail to : " + toAddress;

            MailMessage mail = new MailMessage();
            mail.To.Add(toAddress);
            mail.From = new MailAddress("[email protected]");
            mail.Subject = "Subject: Test Mail";
            mail.Body = messageBody;
            mail.IsBodyHtml = true;            

            //Added this line here
            System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);
            SmtpClient smtp = new SmtpClient();

            smtp.Host = "myhostname.com";            
            smtp.Credentials = new System.Net.NetworkCredential("[email protected]", "");
            smtp.EnableSsl = true;
            smtp.Port = 587;            
            smtp.Send(mail);            
        }


private bool RemoteServerCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    //Console.WriteLine(certificate);
    return true;
}
person Erdnase    schedule 08.10.2018

Если вы получаете эту ошибку при загрузке файлов в S3 с помощью AWS SDK. Убедитесь, что вы выбрали правильный регион для S3.

введите описание изображения здесь

Если вы использовали неправильный регион. Это вернет такую ​​ошибку, которая, кстати, не предназначена для этой ошибки.

person dush88c    schedule 07.06.2021

Это решило мою проблему

smtpClient.Credentials = new NetworkCredential(sendMail.UserName, sendMail.Password);
smtpClient.EnableSsl = false;//sendMail.EnableSSL;

// Со ссылкой на // Проблема возникает только. Используйте строку выше, чтобы установить ложный SSl для устранения ошибки, когда имя пользователя и пароль вводятся в настройках SMTP.

person user3584038    schedule 14.07.2014
comment
Это также отключает безопасность. - person Zoey; 28.12.2014

вот решение, которое я решил использовать.

        ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            string name = certificate.Subject;

            DateTime expirationDate = DateTime.Parse(certificate.GetExpirationDateString());

            if (sslPolicyErrors == SslPolicyErrors.None || (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch && name.EndsWith(".acceptabledomain.com") && expirationDate > DateTime.Now))
            {
                return true;
            }
            return false;
        };
person The Lazy Coder    schedule 23.08.2018

Код из принятого ответа помог мне отладить проблему. Затем я понял, что поле SN аргумента certificate не совпадает с тем, что я считал моим SMTP-сервером. Установив для свойства Host экземпляра SmtpClient значение SN сертификата, я смог исправить проблему.

person ulu    schedule 02.04.2020
comment
Не могли бы вы рассказать подробнее? Я видел поле SN сертификата? - person MarchalPT; 22.04.2021

использовать мою функцию в качестве диагностических сертификатов - см. экран

            System.Net.ServicePointManager.ServerCertificateValidationCallback = Function(s As Object,
                                                                                          cert As System.Security.Cryptography.X509Certificates.X509Certificate,
                                                                                          chain As System.Security.Cryptography.X509Certificates.X509Chain,
                                                                                          err As System.Net.Security.SslPolicyErrors)
                                                                                     Return True
                                                                                 End Function

введите описание изображения здесь

person Viacheslav    schedule 15.02.2021

Не видел, чтобы кто-нибудь указывал на очевидное, что если вы хотите безопасно отлаживать проблемы с SSL, всегда используйте этот подход:

#if DEBUG
    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
#endif

Даже если вы случайно зафиксируете свой код, вы все равно будете в порядке, он не будет скомпилирован в режиме Release.

person keithl8041    schedule 02.06.2021