risposta-alla-domanda-sullo-sviluppo-web-bd.com

"Il certificato remoto non è valido secondo la procedura di convalida". rendere il server SMTP di Gmail

Sto ottenendo questo errore:

Il certificato remoto non è valido in base alla procedura di convalida.

ogni volta che provo a inviare e-mail utilizzando il server SMTP di Gmail nel mio codice C #. Qualcuno può indicarmi la giusta direzione per una soluzione a questo problema?

Quanto segue è la traccia dello stack ...

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)
191
Josh

Attenzione: non usare questo nel codice di produzione!

Come soluzione alternativa, è possibile disattivare la convalida del certificato. Fai sempre questo per ottenere la conferma che l'errore è stato generato a causa di un cattivo certificato.

Chiama questo metodo prima di chiamare 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;
            };
    }
289
Yury Skaletskiy

Il link qui risolto il mio problema.

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

Sono andato all'URL del servizio web (sul server che aveva il problema), ho cliccato sulla piccola icona di sicurezza in IE, che ha portato il certificato. Ho quindi fatto clic sulla scheda Dettagli, ho fatto clic sul pulsante Copia su file, che mi ha permesso di esportare il certificato in un file .cer. Una volta ottenuto il certificato in locale, sono stato in grado di importarlo nell'archivio certificati sul server utilizzando le istruzioni riportate di seguito.

Avvia un nuovo MMC. File -> Aggiungi/Rimuovi snap-in ... Fare clic su Aggiungi ... Scegliere Certificati e fare clic su Aggiungi. Controlla il pulsante di opzione "Account computer". Fare clic su Avanti.

Scegli il computer client nella schermata successiva. Fai clic su Fine. Clicca Chiudi. Clicca OK. ORA installa il certificato nell'archivio certificati Autorità di certificazione fonti attendibili. Ciò consentirà a tutti gli utenti di fidarsi del certificato.

49
T-Rex

È possibile migliorare il codice chiedendo all'utente quando il certificato non è valido se vuole continuare o meno. Vuoi continuare? Come di seguito:

ServicePointManager.ServerCertificateValidationCallback = 
    new RemoteCertificateValidationCallback(ValidateServerCertificate);

E aggiungi un metodo come questo:

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;
    }
}
37
LinuxLover

Un po 'in ritardo per la festa, ma se stai cercando una soluzione come quella di Yury, il seguente codice ti aiuterà a identificare se il problema è correlato a un certificato di auto-firma e, in tal caso, a ignorare l'errore di firma automatica. Ovviamente potresti cercare altri errori SSL se lo desideri.

Il codice che usiamo (per gentile concessione di Microsoft - http://msdn.Microsoft.com/en-us/library/office/dd633677 (v = exchg.80) .aspx ) è il seguente:

  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;
  }
}
26
Hooligancat

Ho avuto lo stesso identico problema e ho capito che di default il Mail Shield di Avast antivirus aveva il "Scan SSL connessione " attivata. Assicurati di disattivarlo .

Da quanto ne so, Avast "apri" la posta, scannerizzala per eventuali virus e poi firmala usando proprio certificato in modo che la posta non venga più firmata dal certificato di gmail che produce quell'errore.

Soluzione 1:

  • Disattiva le scansioni SSL dal tuo antivirus (o dall'intero schermo della posta).

Soluzione 2 (dovrebbe essere la migliore sicurezza di parola):

  • Ottieni in qualche modo il certificato utilizzato dall'antivirus (Avast ha un'opzione per esportarlo)
  • Importalo nel tuo client imap/pop/smtp prima di connetterti al server di Gmail.
15
tehCivilian

Sei sicuro di utilizzare l'indirizzo corretto del server SMTP?

Sia smtp.google.com che smtp.gmail.com funzionano, ma il secondo certificato SSL viene rilasciato.

8

Ottieni lo stesso errore durante l'invio da Outlook a causa di ssl. L'impostazione provata EnableSSL = false ha risolto il problema.

esempio:

var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",                   
                    Port = 587,
                    EnableSsl = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,                   
                    Credentials = new NetworkCredential("[email protected]", "xxxxx")
                };
7

Ho avuto lo stesso errore quando ho provato a inviare email usando SmtpClient via server proxy (Usergate).

Verifica che il certificato contenesse l'indirizzo del server, che non è uguale all'indirizzo del server proxy, quindi l'errore. La mia soluzione: quando si verifica un errore durante il controllo del certificato, ricevere il certificato, esportarlo e controllare.

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

Codice completo della mia classe mittente email:

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

}

7
Evgeny Ivanov

Il mio problema era su Windows 2003 Server, quando si chiamava AuthenticateAsClient. Le soluzioni di cui sopra (ad esempio l'aggiramento di ServicePointManager.ServerCertificateValidationCallback) non hanno funzionato.

Risulta che questo è un bug in Windows 2003, e c'è una correzione:

"Le applicazioni che utilizzano l'API di crittografia non possono convalidare un certificato X.509 in Windows Server 2003"

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

L'installazione di questo hotfix ha risolto il mio problema.

6
user326608

Controlla data e ora del tuo computer. Se è sbagliato, aggiornalo all'ora corrente o impostalo automaticamente per ottenere l'ora da Internet.

Poiché i certificati sono legati a un periodo di tempo fisso, se il tuo orologio è sbagliato, è probabile che tu riceva errori come questo. In tale scenario, fissando il tempo, il problema verrà risolto.

4
AliSafari186

La cartella del tuo sito web richiede la sicurezza del servizio di rete. Soprattutto il web.config. Utilizza questo account per accedere al registro per i certificati. Questo fermerà la necessità di aggiungere un hack al tuo codice.

4
Frans

So di essere in ritardo in questo gioco, ma non ho visto qui una risposta che punta ai log system.diagnostics per il flusso TLS.

Prima di apportare eventuali modifiche al codice, assicurati di capire di cosa si tratta. Il AuthenticationException è una di quella eccezione molto generica che non dice molto. Per sapere cosa sta succedendo, modifica il file app.config per la tua applicazione (o creane uno nuovo) e assicurati di avere traccia System.Net sorgente abilitata nella sezione system.diagnostics, ad esempio:

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

Rieseguire l'applicazione e controllare il file c:\network.log. Dovresti vedere lì informazioni dettagliate sulla tua connessione TLS (SSL), ad esempio:

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

Sapendo quali sono le cause del problema, dovresti essere in grado di risolverlo o almeno di restringere le tue ricerche su Google.

4
lowleveldesign

Il mio problema non era che stavo riferendo il server tramite l'indirizzo IP al posto dell'URL. Avevo acquistato un certificato firmato da una CA per l'uso all'interno di una rete privata. L'URL specificato nel certificato è importante quando si fa riferimento al server. Una volta che ho fatto riferimento al server tramite l'URL nel certificato, tutto ha iniziato a funzionare.

3
Josh

C'è un articolo del blog MSDN su come indagare su questo tipo di problemi:

Risoluzione dei problemi di ASP.NET - Il certificato remoto non è valido secondo la procedura di convalida:
http://blogs.msdn.com/b/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is- invalid-secondo-to-the-validation-procedure.aspx

2
David Burg

Nel nostro caso il problema è stato causato da IIS certificato server. L'oggetto del certificato è stato impostato sul nome DNS e gli utenti stavano tentando di accedere al sito Web tramite indirizzo IP, pertanto la convalida della certificazione .NET non è riuscita. Il problema è scomparso quando gli utenti hanno iniziato a utilizzare il nome DNS.

Quindi devi modificare l'URL del tuo fornitore in https: //CertificateSubject/xxx/xxx.application

2
Ludwo

Per coloro che hanno riscontrato lo stesso errore durante la connessione a un sito locale con un certificato autofirmato, il seguente post del blog mi ha aiutato.

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

2
NullPointer

L'aggiunta di questa linea ha funzionato per me. Questo in effetti si fida di tutti i certificati come menzionato qui . Tuttavia, questo può essere utilizzato principalmente per la risoluzione dei problemi. Se questo funziona per te, significa che il certificato del server remoto non viene aggiunto come certificato attendibile nel tuo computer.

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

Il codice completo è

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;
}
1
Erdnase

Ha risolto il mio problema

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

// Con riferimento a // Viene solo il problema Utilizzare la riga precedente per impostare false SSl per risolvere l'errore quando si immettono nome utente e password nelle impostazioni SMTP.

0
user3584038

ecco la soluzione che ho deciso di usare.

        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;
        };
0
The Lazy Coder