246 votes

"Le certificat distant n'est pas valide selon la procédure de validation" en utilisant le serveur SMTP de Gmail

J'obtiens cette erreur :

Le certificat distant n'est pas valide selon la procédure de validation.

chaque fois que j'essaie d'envoyer un e-mail en utilisant le serveur SMTP de Gmail dans mon code C#. Quelqu'un peut-il m'indiquer la bonne direction pour trouver une solution à ce problème ?

Voici la trace de la pile...

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)

1 votes

Pouvez-vous nous en dire plus sur votre configuration pour utiliser les serveurs SMTP de Gmail ? Mon hypothèse la plus probable : pouvez-vous nous en dire plus sur vos politiques de sécurité pour SSL (comme l'utilisation d'un certificat SSL valide/invalide ?).

0 votes

Pouvez-vous nous donner un exemple de code où vous pouvez reproduire l'erreur ?

316voto

Yury Skaletskiy Points 1333

Attention : n'utilisez pas ceci dans du code de production !

Comme solution de rechange, vous pouvez désactiver la validation des certificats.

Mettez ce code quelque part avant smtpclient.Send() :

ServicePointManager.ServerCertificateValidationCallback =
    delegate(object s, X509Certificate certificate,
             X509Chain chain, SslPolicyErrors sslPolicyErrors)
    { return true; };

191 votes

C'est un hack, pas un correctif ?

93 votes

J'aimerais bien voir une solution, plutôt que de désactiver complètement la sécurité.

76 votes

Pour pallier à un problème de sécurité, vous pouvez désactiver la sécurité ? WTF ?

68voto

T-Rex Points 141

Le lien ici a résolu mon problème.

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

Je me suis rendu à l'URL du service web (sur le serveur qui avait le problème), j'ai cliqué sur la petite icône de sécurité dans IE, ce qui a fait apparaître le certificat. J'ai ensuite cliqué sur l'onglet Détails, puis sur le bouton Copier dans le fichier, ce qui m'a permis d'exporter le certificat sous forme de fichier .cer. Une fois que j'ai eu le certificat localement, j'ai pu l'importer dans le magasin de certificats sur le serveur en utilisant les instructions ci-dessous.

Lancez une nouvelle MMC. Fichier --> Ajouter/Supprimer un Snap-In... Cliquez sur Ajouter... Choisissez Certificats et cliquez sur Ajouter. Cochez le bouton radio "Computer Account". Cliquez sur Next (Suivant).

Choisissez l'ordinateur client dans l'écran suivant. Cliquez sur Terminer. Cliquez sur Fermer. Cliquez sur OK. Installez maintenant le certificat dans le magasin de certificats des autorités de certification racine de confiance. Cela permettra à tous les utilisateurs de faire confiance au certificat.

0 votes

+1 lors de l'importation d'un certificat via l'outil d'importation sur le cert et non via le snap in, il est seulement pour votre compte utilisateur. L'utilisation du snap in vous permet de choisir pour qui l'importation est destinée, compte utilisateur, compte de service ou tout le monde. Merci pour votre indication. Je me suis gratté la tête pendant une minute ou deux !

2 votes

Si vous voulez utiliser la ligne de commande pour automatiser sur tous les postes de travail de dev/test - certutil -f -p test -importPFX Root devcert.pfx et certutil -f -p test -importPFX MY devcert.pfx . Doit être exécuté dans une invite de commande administrateur (en supposant que le mot de passe PFX est test )

0 votes

C'est la meilleure façon de résoudre le problème si vous utilisez un certificat auto-signé pour les tests, merci T-Rex !

36voto

LinuxLover Points 301

Vous pouvez améliorer le code pour demander à l'utilisateur que le certificat n'est pas valide. Voulez-vous continuer ? Comme ci-dessous :

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

Et ajoutez une méthode comme celle-ci :

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

61 votes

Qui va cliquer sur le bouton "Continuer", s'il s'agit d'une application en nuage ?

14voto

J'obtiens la même erreur en envoyant depuis outlook à cause du ssl. J'ai essayé de régler EnableSSL = false pour résoudre le problème.

exemple :

var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",                   
                    Port = 587,
                    EnableSsl = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,                   
                    Credentials = new NetworkCredential("xxx@gmail.com", "xxxxx")
                };

3 votes

Gmail ne vous permet pas de vous connecter si vous réglez SSL sur false, j'ai essayé votre solution mais cela n'a pas fonctionné pour moi.

0 votes

Oui, c'est ce que j'appelle "basique" (par opposition à "none" ou "ssl")........ Ces paramètres de messagerie sont parfois délicats.

9voto

Pawel Lesnikowski Points 3634

Êtes-vous sûr d'utiliser l'adresse correcte du serveur SMTP ?

Les deux sites smtp.google.com et smtp.gmail.com fonctionnent, mais le certificat SSL est émis pour le second.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X