我得到这个错误:

根据验证过程,远端证书无效。

每当我试图在我的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)

当前回答

这有点晚了,但如果您正在寻找像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;
  }
}

其他回答

如果您在使用AWS SDK将文件上传到S3时遇到此错误。确保为S3选择了正确的区域。

如果您使用了不正确的区域。这将返回这样一个错误,这不是为这个错误顺便说一句。

警告:不要在产品代码中使用此代码!

作为一种解决方法,您可以关闭证书验证。只有在确认由于错误的证书而引发错误时才这样做。

在调用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;
        };
}

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

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

我去到web服务的url(在有问题的服务器上),点击IE中的小安全图标,弹出证书。然后,我单击Details选项卡,单击Copy To File按钮,这允许我将证书导出为.cer文件。在本地获得证书后,我就可以使用下面的说明将其导入服务器上的证书存储区。

开始一个新的MMC。 文件——>添加/删除管理单元… 单击Add…… 选择“证书”,单击“添加”。 选中“计算机帐户”单选按钮。单击Next。

在下一个屏幕中选择客户端计算机。单击Finish。 单击Close。 单击OK。 现在将证书安装到受信任的根证书颁发机构证书存储区中。这将允许所有用户信任该证书。

当我试图通过代理服务器(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);
}

}

我知道我在这个游戏中已经很晚了,但我还没有看到指向系统的答案。TLS流的诊断日志。

在对代码进行任何更改之前,请确保您了解问题所在。AuthenticationException是一种非常通用的异常,它没有透露太多信息。要了解底层的工作原理,请编辑应用程序的app.config文件(或创建一个新文件),并确保拥有System。在系统中启用网络跟踪源。诊断部分,例如:

<?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>

重新运行应用程序并检查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..

知道了问题的原因,您应该能够解决它,或者至少缩小您的谷歌搜索范围。