„Zdalny certyfikat jest nieważny zgodnie z procedurą sprawdzania poprawności.” za pomocą serwera SMTP Gmaila

221

Otrzymuję ten błąd:

Zdalny certyfikat jest nieważny zgodnie z procedurą sprawdzania poprawności.

za każdym razem, gdy próbuję wysłać e-mail za pomocą serwera SMTP Gmaila w moim kodzie C #. Czy ktoś może wskazać mi właściwy kierunek rozwiązania tego problemu?

Poniżej znajduje się ślad stosu ...

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)
Josh
źródło
1
Czy możesz nam powiedzieć więcej o swojej konfiguracji korzystania z serwerów SMTP Gmaila? Moje szczęście: czy możesz nam powiedzieć więcej na temat twoich zasad bezpieczeństwa dla SSL (np. Używając ważnego / nieważnego certyfikatu SSL?).
Brian Clozel
Czy możesz podać nam próbkę kodu, w której możesz odtworzyć błąd?
zaTricky,

Odpowiedzi:

302

Ostrzeżenie: nie używaj tego w kodzie produkcyjnym!

Aby obejść ten problem, możesz wyłączyć sprawdzanie poprawności certyfikatu. Rób to tylko w celu uzyskania potwierdzenia, że ​​błąd jest generowany z powodu złego certyfikatu.

Wywołaj tę metodę, zanim zadzwonisz 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;
            };
    }
Jurij Skaletski
źródło
174
To jest hack, a nie naprawa?
LB.
88
Chciałbym zobaczyć poprawkę, zamiast całkowicie wyłączać wszystkie zabezpieczenia.
Roman Starkov
71
jako obejście problemu bezpieczeństwa możesz wyłączyć bezpieczeństwo? WTF?
John Nicholas,
68
Musiałem zlekceważyć to, ponieważ ludzie nadal myślą, że to rozwiązanie. To WŁAŚNIE Wyłączanie bezpieczeństwo. NIE UŻYWAJ W PRODUKCJI , ludzie. On nawet tak mówi. Do licha.
MGOwen
51
Pozytywne. W pełni zgadzam się, że nie należy tego używać w produkcji ALE .. Robię prototyp czegoś. Serwer testowy, który udostępnili mi, zmusił mnie do korzystania z protokołu SSL. Praca z certyfikatami jest dla mnie całkiem nowa, więc po prostu chcę SZYBKIEGO WYKORZYSTANIA
TweeZz
58

Link tutaj rozwiązał mój problem.

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

Poszedłem do adresu URL usługi internetowej (na serwerze, na którym wystąpił problem), kliknąłem małą ikonę bezpieczeństwa w IE, która wywołała certyfikat. Następnie kliknąłem kartę Szczegóły, kliknąłem przycisk Kopiuj do pliku, co pozwoliło mi wyeksportować certyfikat jako plik .cer. Gdy miałem certyfikat lokalnie, byłem w stanie zaimportować go do magazynu certyfikatów na serwerze, korzystając z poniższych instrukcji.

Uruchom nową MMC. Plik -> Dodaj / Usuń przystawkę ... Kliknij Dodaj ... Wybierz Certyfikaty i kliknij Dodaj. Zaznacz przycisk opcji „Konto komputera”. Kliknij Następny.

Wybierz komputer kliencki na następnym ekranie. Kliknij przycisk Zakończ. Kliknij Zamknij. Kliknij OK. TERAZ zainstaluj certyfikat w magazynie certyfikatów Zaufane główne urzędy certyfikacji. Umożliwi to wszystkim użytkownikom zaufanie do certyfikatu.

T-Rex
źródło
+1 podczas importowania certyfikatu za pomocą narzędzia do importowania certyfikatu, a nie poprzez przystawkę, dotyczy tylko twojego konta użytkownika. Korzystanie z przystawki pozwala wybrać, dla kogo ma być importowany, konto użytkownika, konto usługi lub wszyscy. Dziękuję za twój wskaźnik. Drapałem się tam przez minutę lub dwie!
davidb
Jeśli chcesz użyć wiersza polecenia do automatyzacji na wszystkich stacjach roboczych deweloperskich / testowych - certutil -f -p test -importPFX Root devcert.pfxi certutil -f -p test -importPFX MY devcert.pfx. Musi zostać uruchomiony w wierszu polecenia administratora (przy założeniu, że hasło test
PFX
Jest to najlepszy sposób, aby to naprawić, jeśli używasz samopodpisanego certyfikatu do testowania, dzięki T-Rex!
ToastyMallows
37

Możesz poprawić kod, pytając użytkownika, kiedy certyfikat jest nieważny, czy chce kontynuować, czy nie. Czy chcesz kontynuować? Jak poniżej:

ServicePointManager.ServerCertificateValidationCallback = 
    new RemoteCertificateValidationCallback(ValidateServerCertificate);

I dodaj taką metodę:

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;
    }
}
LinuxLover
źródło
50
Kto kliknie przycisk „Kontynuuj”, jeśli jest to aplikacja w chmurze?
Konstantin Isaev
34

Trochę za późno na imprezę, ale jeśli szukasz rozwiązania takiego jak Yury, poniższy kod pomoże ci ustalić, czy problem dotyczy certyfikatu z podpisem własnym, a jeśli tak, zignoruj ​​błąd samopodpisania. Możesz oczywiście sprawdzić inne błędy SSL, jeśli chcesz.

Używany przez nas kod (dzięki uprzejmości Microsoft - http://msdn.microsoft.com/en-us/library/office/dd633677(v=exchg.80).aspx ) jest następujący:

  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;
  }
}
Chuligancat
źródło
1
W moim przypadku sslPolicyErrors to RemoteCertificateNameMismatch i zmodyfikowałem sprawdzanie certyfikatu, ponieważ nie mieliśmy takich samych wartości podmiotu i wystawcy.
Ufuk Hacıoğulları
2
X509Certyfikat używany przez serwer Exchange ciągle przełączał się między samopodpisanym a zaufanym. Użycie tego kodu pomogło administratorowi sieci i mnie nie tylko dowiedzieć się, że tak jest, ale również całkowicie rozwiązało problem, pomijając certyfikaty z podpisem własnym. To było idealne!
Bret
20

Miałem dokładnie ten sam problem i zorientowałem się, że domyślnie Ochrona poczty z programu antywirusowego Avast ma aktywowane „Skanuj połączenie SSL” . Upewnij się, aby to wyłączyć .

Z mojej wiedzy Avast „otworzy” pocztę, skanuje ją w poszukiwaniu wirusów, a następnie podpisuje za pomocą własnego certyfikatu, aby poczta nie była już podpisywana przez certyfikat gmail, który powoduje ten błąd.

Rozwiązanie 1:

  • Wyłącz skanowanie SSL w swoim programie antywirusowym (lub całej osłonie poczty).

Rozwiązanie 2 (powinno być najlepszym językiem bezpieczeństwa):

  • Uzyskaj w jakiś sposób certyfikat używany przez program antywirusowy (Avast ma opcję wyeksportowania go)
  • Zaimportuj go do swojego klienta imap / pop / smtp przed połączeniem z serwerem Gmail.
tehCivilian
źródło
1
Zaoszczędziłeś mi tyle czasu. Odwiedzenie wieczności sprawiłoby, że mój program antywirusowy byłby winien, a nie mój kod.
arao6,
13

Uzyskaj ten sam błąd podczas wysyłania z programu Outlook z powodu ssl. Sprawdzone ustawienie EnableSSL = false rozwiązało problem.

przykład:

var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",                   
                    Port = 587,
                    EnableSsl = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,                   
                    Credentials = new NetworkCredential("[email protected]", "xxxxx")
                };
Chitra Pannirselvam
źródło
3
Gmail nie zezwala na połączenie, gdy ustawisz SSL na false, próbowałem Twojego rozwiązania, które nie działało dla mnie.
Zeeshan Ajmal
Tak, to jest to, co nazywam „podstawowym” (w porównaniu do „none” lub „ssl”) ....... te ustawienia e-mail są czasem trudne.
granadaCoder
9

Czy na pewno używasz prawidłowego adresu serwera SMTP?

Zarówno smtp.google.com, jak i smtp.gmail.com działają, ale certyfikat SSL jest wydawany drugiemu.

Paweł Lesnikowski
źródło
9

Miałem ten sam błąd, gdy próbowałem wysłać wiadomość e-mail za SmtpClientpośrednictwem serwera proxy (Usergate).

Sprawdza, czy certyfikat zawiera adres serwera, który nie jest równy adresowi serwera proxy, stąd błąd. Moje rozwiązanie: gdy podczas sprawdzania certyfikatu wystąpi błąd, otrzymaj certyfikat, wyeksportuj go i sprawdź.

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);
    }

Pełny kod mojej klasy nadawcy e-maila:

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);
}

}

Jewgienij Iwanow
źródło
7

Wiem, że jestem spóźniony w tej grze, ale nie widziałem tutaj odpowiedzi wskazującej na logi systemowe.diagnostics dla strumienia TLS.

Przed wprowadzeniem jakichkolwiek zmian w kodzie upewnij się, że rozumiesz, na czym polega problem. Jest AuthenticationExceptionto jeden z bardzo ogólnych wyjątków, który niewiele mówi. Aby dowiedzieć się, co dzieje się pod maską, edytuj plik app.config dla swojej aplikacji (lub utwórz nowy) i upewnij się, że masz włączone źródło śledzenia System.Net w system.diagnosticssekcji, na przykład:

<?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>

Uruchom ponownie aplikację i sprawdź plik c: \ network.log. Powinieneś zobaczyć tam szczegółowe informacje na temat połączenia TLS (SSL), na przykład:

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..

Wiedząc, co powoduje problem, powinieneś być w stanie go rozwiązać lub przynajmniej zawęzić wyszukiwanie w Google.

lowleveldesign
źródło
6

Mój problem dotyczył systemu Windows 2003 Server podczas wywoływania AuthenticateAsClient. Powyższe rozwiązania (np. Obchodzenie ServicePointManager.ServerCertificateValidationCallback) nie działały.

Okazuje się, że jest to błąd w systemie Windows 2003 i jest poprawka:

„Aplikacje korzystające z interfejsu API kryptografii nie mogą sprawdzić poprawności certyfikatu X.509 w systemie Windows Server 2003”

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

Zainstalowanie tej poprawki rozwiązało mój problem.

użytkownik326608
źródło
4

Folder witryny wymaga zabezpieczeń usługi sieciowej. Zwłaszcza web.config. Używa tego konta, aby uzyskać dostęp do rejestru certyfikatów. To powstrzyma potrzebę dodawania hacka do twojego kodu.

Frans
źródło
4

Moim problemem nie było to, że odwoływałem się do serwera za pomocą adresu IP zamiast adresu URL. Kupiłem podpisany certyfikat od urzędu certyfikacji do użytku w sieci prywatnej. Adres URL określony w certyfikacie ma znaczenie, gdy odwołuje się do serwera. Gdy tylko odwołałem się do serwera przez adres URL w certyfikacie, wszystko zaczęło działać.

Josh
źródło
Ta odpowiedź zasługuje na wyższą wartość, ponieważ wskazuje na powszechny błąd; ludzie (w tym ja) sądzą, że host ma na celu jedynie znalezienie serwera.
Mojtaba
4

Sprawdź datę i godzinę komputera. Jeśli jest niepoprawny, zaktualizuj go do bieżącej godziny lub ustaw ją automatycznie, aby uzyskać czas z Internetu.

Ponieważ certyfikaty są powiązane z ustalonym przedziałem czasowym, jeśli twój zegar jest nieprawidłowy, prawdopodobnie wystąpią takie błędy. W tym scenariuszu przez ustalenie czasu problem zostanie rozwiązany.

AliSafari186
źródło
1
Jeśli data systemowa jest „za daleko” od bieżącej godziny, ważność certyfikatu otrzymanego od Google powoduje problem. Widzi wydane i ważne dla informacji, które nie mają dużo aktualnego czasu. To nie jedyna rzecz, która nie może powodować tego problemu. Ale z pewnością taki może.
phil soady
1
Niezwykle przydatne przypomnienie, aby dokładnie to sprawdzić w moim przypadku! Brzytwa Ockhama i tak dalej ... :) A teraz ta bateria CMOS ...
Mike G
2

W naszym przypadku problem był spowodowany certyfikatem serwera IIS. Temat certyfikatu został ustawiony na nazwę DNS, a użytkownicy próbowali uzyskać dostęp do strony internetowej za pomocą adresu IP, więc weryfikacja certyfikatu .NET nie powiodła się. Problem zniknął, gdy użytkownicy zaczęli używać nazwy DNS.

Musisz więc zmienić adres URL dostawcy na https: //CertificateSubject/xxx/xxx.application

Ludwo
źródło
Czy możesz to rozwinąć? W moim przypadku aplikacja działa na jednym serwerze i nie działa na drugim. Nie mam pojęcia ... Nie jestem ekspertem, ale domena jest nadal połączona z działającą, a certyfikat serwera jest już zainstalowany na obu komputerach. Nadal nie rozumiem, dlaczego to może być tak ważne, ponieważ mówi „zdalny certyfikat”.
Michael Brennt,
1

Dodanie tej linii działało dla mnie. To faktycznie ufa wszystkim certyfikatom wymienionym tutaj . Można to jednak wykorzystać przede wszystkim do rozwiązywania problemów. Jeśli to działa, oznacza to, że certyfikat zdalnego serwera nie został dodany jako zaufany certyfikat na twoim komputerze.

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

Pełny kod to

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;
}
Erdnase
źródło
0

To rozwiązało mój problem

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

// W odniesieniu do // Problem występuje tylko Użyj powyższej linii, aby ustawić fałszywy SSl, aby rozwiązać błąd, gdy nazwa użytkownika i hasło zostaną wprowadzone w ustawieniach SMTP.

użytkownik3584038
źródło
13
To także wyłącza bezpieczeństwo.
Zoey
0

oto rozwiązanie, z którego zdecydowałem się skorzystać.

        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;
        };
Lazy Coder
źródło
0

Kod z zaakceptowanej odpowiedzi pomógł mi debugować problem. Wtedy zdałem sobie sprawę, że pole SN certificateargumentu nie było takie samo, jak myślałem, że to mój serwer SMTP. Ustawiając Hostwłaściwość instancji SmtpClient na wartość SN certyfikatu, udało mi się rozwiązać problem.

ulu
źródło