我得到这个错误:
根据验证过程,远端证书无效。
每当我试图在我的c#代码中使用Gmail的SMTP服务器发送电子邮件时。
有人能给我指出解决这个问题的正确方向吗?
下面是堆栈跟踪…
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)
当我试图通过代理服务器(Usergate)使用SmtpClient发送电子邮件时,我有同样的错误。
验证包含服务器地址的证书,该证书不等于代理服务器地址,因此出现错误。
我的解决方案:当检查证书时发生错误,接收证书,导出并检查。
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);
}
}
当我试图通过代理服务器(Usergate)使用SmtpClient发送电子邮件时,我有同样的错误。
验证包含服务器地址的证书,该证书不等于代理服务器地址,因此出现错误。
我的解决方案:当检查证书时发生错误,接收证书,导出并检查。
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);
}
}