使用Gmail SMTP服务器“远程证书根据validation程序无效”

我得到这个错误:

根据validation程序,远程证书无效。

每当我尝试使用Gmail的SMTP服务器在我的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) 

警告:不要在生产代码中使用它!

作为解决方法,您可以closures证书validation。

把这个代码放在smtpclient.Send()之前的某个地方:

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

这里的链接解决了我的问题。

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

我去了Web服务的URL(在有问题的服务器上),点击IE中的小安全图标,它提出了证书。 然后我点击详细信息选项卡,点击复制到文件button,这使我可以导出certifcate作为.cer文件。 一旦我在本地获得证书,就可以使用以下说明将其导入服务器上的证书存储区。

启动一个新的MMC。 文件 – >添加/删除pipe理单元…单击添加…select证书,然后单击添加。 检查“计算机帐户”单选button。 点击下一步。

在下一个屏幕中select客户端计算机。 点击完成。 点击closures。 点击OK。 现在将证书安装到受信任的根证书颁发机构证书存储中。 这将允许所有用户信任证书。

您可以改进代码来询问用户证书是否无效。 你想继续吗? 如下:

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

晚会有点晚,但是如果你正在寻找像Yury这样的解决scheme,下面的代码将帮助你确定问题是否与自签名证书相关,如果是的话,忽略自签名错误。 如果你愿意的话,你显然可以检查其他的SSL错误。

我们使用的代码(微软提供 – 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; } } 

由于ssl而从outlook发送时出现同样的错误。 尝试设置EnableSSL = false解决了这个问题。

例:

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

我有完全相同的问题,并指出,默认情况下,Avast杀毒软件的Mail Shield已激活“扫描SSL连接” 。 确保将其closures

据我所知,Avast会“打开”邮件,扫描它的病毒,然后使用自己的证书签名,这样邮件就不会再被gmail的证书签名,从而产生错误。

解决scheme1:

  • closures您的防病毒(或整个邮件盾)的SSL扫描。

解决scheme2(应该是最安全的说法):

  • 获取防病毒软件使用的证书(Avast可以select导出)
  • 在连接到Gmail服务器之前,将其导入到您的imap / pop / smtp客户端中。

你确定你正在使用正确的SMTP服务器地址?

smtp.google.com和smtp.gmail.com都能正常工作,但是SSL证书发给第二个。

我的问题是在Windows 2003 Server上调用AuthenticateAsClient时。 上面的解决scheme(例如绕过ServicePointManager.ServerCertificateValidationCallback )不起作用。

原来这是Windows 2003中的一个错误,并且有一个修补程序:

“使用encryptionAPI的应用程序无法validationWindows Server 2003中的X.509证书”

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

安装此修补程序解决了我的问题。

您的网站文件夹需要networking服务安全。 特别是web.config。 它使用此帐户访问您的registry的证书。 这将停止需要添加黑客到您的代码。

设置您的计算机date和时间最新,问题将被修复

当我尝试通过代理服务器(Usergate)使用SmtpClient发送电子邮件时,发生了同样的错误。

validation包含服务器地址的证书,这不等于代理服务器的地址,因此是错误的。 我的解决scheme:当检查证书时发生错误,接收证书,导出并检查。

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

}

对于使用自签名证书连接到本地站点时遇到同样错误的人,以下博客帮助我解决了这个问题。

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

它解决了我的问题

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

//参照//只有问题出现在SMTP设置中input用户名和密码时,使用上面的行来设置错误的SSl来解决错误。

有一个关于调查这种types的问题的MSDN博客文章:

疑难解答ASP.NET – 根据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

我的问题不是我通过IP地址而是通过URL来引用服务器。 我已经从一个CA购买了一个签名的证书在专用networking中使用。 引用服务器时,证书上指定的URL确实很重要。 一旦我通过证书中的URL引用服务器,一切都开始工作。

 smtpClient.Credentials = new NetworkCredential(sendMail.UserName, sendMail.Password); smtpClient.EnableSsl = false;//sendMail.EnableSSL; // With Reference to // Problem comes only 

当在SMTP设置中input用户名和密码时,使用上面的行设置错误的SSl来解决错误。

在我们的情况下,问题是由IIS服务器证书引起的。 证书的主题被设置为DNS名称,用户试图通过IP地址访问网站,所以.NETauthenticationvalidation失败。 当用户开始使用DNS名称时,问题消失了。

所以你必须改变你的提供者URL为https://CertificateSubject/xxx/xxx.application