"Le certificat à distance n'est pas valable selon la procédure de validation."utilisant le serveur SMTP Gmail
je reçois cette erreur:
le certificat à distance n'est pas valable 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)
19 réponses
Attention: Ne l'utilisez pas dans le code de production!
comme solution de rechange, vous pouvez désactiver la validation du certificat. Seulement faites ceci pour obtenir la confirmation que l'erreur est jeté à cause d'un mauvais certificat.
appelez cette méthode avant d'appeler 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;
};
}
le lien ici a résolu mon problème.
http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html
je suis allé à l'url du service web (sur le serveur qui avait le problème), cliqué sur la petite icône de sécurité dans IE, qui a soulevé le certificat. J'ai ensuite cliqué sur L'onglet Détails, cliqué sur le bouton Copier vers le fichier, ce qui m'a permis d'exporter le certificat comme un .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.
lancer un nouveau MMC. Fichier --> Ajouter/Supprimer Un Composant Logiciel Enfichable... Cliquez Sur Ajouter... Choisissez les certificats et cliquez sur Ajouter. Vérifiez le bouton radio "Compte D'ordinateur". Cliquez Sur Suivant.
Choisir l'ordinateur client dans l'écran suivant. Cliquez Sur Terminer. Cliquez Sur Fermer. Cliquez sur OK. Maintenant, installez le certificat dans le certificat des Autorités de Certification racine de confiance. stocker. Cela permettra à tous les utilisateurs de faire confiance au certificat.
, Vous pouvez améliorer le code à demander à l'utilisateur que le certificat n'est pas valide. Voulez-vous continuer? Comme ci-dessous:
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
et ajouter 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;
}
}
un peu tard pour la partie, mais si vous cherchez une solution comme Yury le code suivant vous aidera à déterminer si la question est liée à un certificat auto-signe et, si oui, ignorer l'erreur auto-signe. Vous pouvez évidemment vérifier la présence d'autres erreurs SSL si vous le souhaitez.
le code que nous utilisons (gracieuseté de Microsoft - http://msdn.microsoft.com/en-us/library/office/dd633677 (V = echg.80).aspx ) est le suivant:
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;
}
}
j'ai eu exactement le même problème et j'ai compris que par défaut le mail Shield D'Avast antivirus avait le " Scan SSL connection " activé. Assurez-vous de éteignez .
à ma connaissance, Avast va " ouvrir " le courrier, le scanner pour tous les virus et puis le signer en utilisant son propre certificat de sorte que le courrier ne sera pas signé par le gmail certificat plus qui produit cette erreur.
Solution 1:
- désactivez les scans SSL de votre antivirus (ou de l'ensemble de l'écran de messagerie).
Solution 2 (qui Devrait être la meilleure sécurité parlant):
- Obtenir en quelque sorte le certificat utilisé par l'antivirus (Avast a une option pour exporter)
- Importez-le dans votre client imap/pop/smtp avant de vous connecter à gmail server.
êtes-vous sûr d'utiliser la bonne adresse de serveur SMTP?
les deux smtp.google.com et smtp.gmail.com travail, mais le certificat SSL est délivré à la seconde.
obtenir la même erreur tout en envoyant d'outlook en raison de ssl. Essayer de définir EnableSSL = false a résolu 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")
};
j'ai eu la même erreur lorsque j'ai essayé d'envoyer un e-mail en utilisant SmtpClient
via le serveur proxy (Usergate).
Vérifie le certificat d'origine contient l'adresse du serveur, ce qui n'est pas égale à l'adresse du serveur proxy, d'où l'erreur. Ma solution: lorsqu'une erreur se produit lors de la vérification du certificat, recevez le certificat, exportez-le et vérifiez.
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);
}
code complet de ma classe d'expéditeur de courrier électronique:
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);
}
}
mon problème était sur Windows 2003 Server, lors de L'appel de AuthenticateAsClient. Les solutions ci-dessus (par exemple contourner ServicePointManager.ServerCertificateValidationCallback
) n'ont pas fonctionné.
S'avère que C'est un bug dans Windows 2003, et il y a un hotfix:
"les Applications qui utilisent L'API de cryptographie ne peuvent pas valider un certificat X. 509 dans Windows Server 2003"
https://support.microsoft.com/en-us/kb/938397
L'installation de ce correctif a résolu mon problème.
votre dossier de site Web a besoin d'un service de sécurité réseau. En particulier le web.config. Il utilise ce compte pour accéder à votre registre pour les certificats. Cela empêchera d'ajouter un hack à votre code.
Vérifiez la Date et L'Heure de votre ordinateur. S'il est erroné, mettez-le à jour à l'heure actuelle ou réglez-le automatiquement pour obtenir l'heure à partir de L'Internet.
parce que les certificats sont liés à une période de temps fixe, si votre horloge est erronée, Vous êtes susceptible d'obtenir des erreurs de ce genre. Dans ce scénario, en fixant le temps, le problème sera résolu.
mon problème n'était pas que je faisais référence au serveur par l'adresse IP au lieu de L'URL. J'avais acheté un certificat signé D'une AC pour utilisation dans un réseau privé. L'URL spécifiée sur le certificat n'a pas d'importance lorsque vous référencez le serveur. Une fois que j'ai référencé le serveur par L'URL dans le certificat, tout a commencé à fonctionner.
pour ceux qui rencontrent cette même erreur en se connectant à un site local avec un certificat auto-signé, le billet de blog suivant m'a aidé.
http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html
dans notre cas, le problème a été causé par le certificat de serveur IIS. Le sujet du certificat était défini au nom DNS et les utilisateurs essayaient d'accéder au site Web par adresse IP, donc la validation de certification .NET a échoué. Le problème a disparu lorsque les utilisateurs ont commencé à utiliser le nom DNS.
donc vous devez changer L'URL de votre fournisseur en https://CertificateSubject/xxx/xxx.application
Il ya un article de blog MSDN sur l'enquête de ce type de questions:
dépannage ASP.NET – le certificat distant n'est pas valide selon la procédure de validation:
http://blogs.msdn.com/b/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is-invalid-according-to-the-validation-procedure.aspx
ajouter cette ligne a fonctionné pour moi.
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);
code complet est
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("from@mydomain.com");
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("sender@sample.com", "");
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;
}
Il a résolu mon problème de
smtpClient.Credentials = new NetworkCredential(sendMail.UserName, sendMail.Password);
smtpClient.EnableSsl = false;//sendMail.EnableSSL;
/ / en référence à / / problème vient seulement L'utilisation au-dessus de la ligne pour définir faux SSl pour résoudre l'erreur lorsque le nom d'utilisateur et le mot de passe est entré dans les paramètres SMTP.
voici la solution que j'ai décidé d'utiliser.
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;
};
je sais que je suis assez en retard dans ce jeu, mais je n'ai pas vu une réponse ici pointant vers le système.journal des diagnostics pour le flux TLS.
avant de modifier votre code, assurez-vous de bien comprendre de quoi il s'agit. Le AuthenticationException
est l'une de cette exception très générique qui ne dit pas grand chose. Pour apprendre ce qui se passe sous le capot éditez l'application.fichier de configuration pour votre application (ou créer un nouveau) et assurez-vous que vous avez System.Net trace source activée dans la section system.diagnostics
, par exemple:
<?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>
relancez votre application et vérifiez c:\network.le fichier de log. Vous devriez y voir des informations détaillées sur votre connexion TLS (SSL), par exemple:
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..
sachant ce qui cause le problème, vous devriez être en mesure de le résoudre ou au moins restreindre vos recherches Google.