我收到这个错误:
根据验证程序,远程证书无效.
每当我尝试使用我的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)
Run Code Online (Sandbox Code Playgroud)
小智 297
警告:不要在生产代码中使用它!
作为解决方法,您可以关闭证书验证.只有这样才能获得由于证书错误而导致错误丢失的确认.
在致电之前调用此方法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;
};
}
Run Code Online (Sandbox Code Playgroud)
小智 52
这里的链接解决了我的问题.
http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html
我去了网络服务的网址(在有问题的服务器上),点击了IE中的小安全图标,它提出了证书.然后我单击Details选项卡,单击Copy To File按钮,这允许我将certifcate导出为.cer文件.一旦我在本地获得了证书,我就可以使用以下说明将其导入服务器上的证书存储区.
启动一个新的MMC.文件 - >添加/删除管理单元...单击添加...选择证书,然后单击添加.选中"计算机帐户"单选按钮.点击下一步.
在下一个屏幕中选择客户端计算机.单击完成.单击关闭.单击确定.现在将证书安装到受信任的根证书颁发机构证书存储区.这将允许所有用户信任该证书.
小智 38
您可以改进代码以询问用户证书无效.你想继续吗?如下:
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
Run Code Online (Sandbox Code Playgroud)
并添加如下方法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Hoo*_*cat 29
派对有点晚,但如果您正在寻找像Yury这样的解决方案,以下代码将帮助您确定问题是否与自签名证书相关,如果是,则忽略自签名错误.如果您愿意,您显然可以检查其他SSL错误.
我们使用的代码(由Microsoft提供 - 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;
}
}
Run Code Online (Sandbox Code Playgroud)
teh*_*ian 17
我遇到了完全相同的问题,并且发现默认情况下,Avast防病毒软件的Mail Shield激活了"扫描SSL连接".一定要关闭它.
根据我的知识,Avast将"打开"邮件,扫描它以查找任何病毒,然后使用它自己的证书对其进行签名,这样邮件就不会再被gmail的证书签名而产生该错误.
解决方案1:
解决方案2(应该是最好的安全性说法):
小智 8
因为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")
};
Run Code Online (Sandbox Code Playgroud)
当我尝试使用SmtpClient通过代理服务器(Usergate)发送电子邮件时,我遇到了同样的错误.
验证证书包含服务器的地址,该地址不等于代理服务器的地址,因此错误.我的解决方案:检查证书时发生错误,接收证书,导出并检查.
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);
}
Run Code Online (Sandbox Code Playgroud)
我的电子邮件发件人类的完整代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
}
我的问题是在Windows 2003 Server上调用AuthenticateAsClient时.上述解决方案(例如规避ServicePointManager.ServerCertificateValidationCallback)不起作用.
原来这是Windows 2003中的一个错误,并且有一个修补程序:
"使用Cryptography API的应用程序无法验证Windows Server 2003中的X.509证书"
https://support.microsoft.com/en-us/kb/938397
安装此修补程序解决了我的问题.
下面的代码在 dotnetcore 中为我工作以绕过 ssl 证书
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
using (var client = new HttpClient(httpClientHandler))
{
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题不是我通过 IP 地址而不是 URL 来引用服务器。我从 CA 购买了一个签名证书,用于在专用网络中使用。在引用服务器时,证书上指定的 URL 很重要。一旦我通过证书中的 URL 引用了服务器,一切就开始工作了。
我知道我在这场比赛中已经很晚了,但是我在这里没有看到指向TLS流的system.diagnostics日志的答案。
在对代码进行任何更改之前,请确保您了解问题所在。这AuthenticationException是一个非常普通的异常之一,它并不能说明很多问题。要了解实际情况,请为您的应用程序编辑app.config文件(或创建一个新文件),并确保在该部分中启用了System.Net跟踪源system.diagnostics,例如:
<?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>
Run Code Online (Sandbox Code Playgroud)
重新运行您的应用程序,然后检查c:\ network.log文件。您应该在此处看到有关TLS(SSL)连接的详细信息,例如:
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..
Run Code Online (Sandbox Code Playgroud)
知道导致问题的原因后,您应该能够解决问题,或者至少缩小Google搜索范围。
添加这一行对我有用。事实上,这信任此处提到的所有证书。但是,这主要可用于故障排除。如果这对您有效,则意味着远程服务器的证书未添加为您的计算机中的受信任证书。
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);
Run Code Online (Sandbox Code Playgroud)
完整代码是
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
400701 次 |
| 最近记录: |