“ ใบรับรองระยะไกลไม่ถูกต้องตามขั้นตอนการตรวจสอบความถูกต้อง” ใช้เซิร์ฟเวอร์ Gmail SMTP


222

ฉันได้รับข้อผิดพลาดนี้:

ใบรับรองระยะไกลไม่ถูกต้องตามขั้นตอนการตรวจสอบความถูกต้อง

เมื่อใดก็ตามที่ฉันพยายามส่งอีเมลโดยใช้เซิร์ฟเวอร์ SMTP ของ Gmail ในรหัส 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)

1
คุณสามารถบอกเราเพิ่มเติมเกี่ยวกับการกำหนดค่าการใช้เซิร์ฟเวอร์ Gmail SMTP ได้หรือไม่ การคาดเดาโชคดีของฉัน: คุณสามารถบอกเราเพิ่มเติมเกี่ยวกับนโยบายความปลอดภัยของคุณเกี่ยวกับ SSL (เช่นการใช้ใบรับรอง SSL ที่ถูกต้อง / ไม่ถูกต้องหรือไม่)
ไบรอัน Clozel

คุณสามารถให้รหัสตัวอย่างแก่เราซึ่งคุณสามารถสร้างข้อผิดพลาดได้หรือไม่?
zaTricky

คำตอบ:


302

คำเตือน: อย่าใช้สิ่งนี้ในรหัสการผลิต!

คุณสามารถปิดการตรวจสอบใบรับรองได้ ทำเช่นนี้เท่านั้นเพื่อรับการยืนยันว่าข้อผิดพลาดกำลังถูกส่งเนื่องจากใบรับรองไม่ถูกต้อง

เรียกวิธีนี้ก่อนที่จะโทร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;
            };
    }

175
นี่คือการแฮกไม่ใช่การแก้ไขใช่ไหม
LB.

88
ชอบที่จะเห็นการแก้ไขมากกว่าการปิดการรักษาความปลอดภัยทั้งหมดอย่างสมบูรณ์
Roman Starkov

71
วิธีแก้ไขปัญหาด้านความปลอดภัยคุณสามารถปิดการรักษาความปลอดภัยได้หรือไม่ WTF?
John Nicholas

68
ต้องลดระดับลงเพราะคนยังคิดว่ามันเป็นทางออก เป็นเพียงการปิดความปลอดภัย ห้ามใช้ในการผลิตผู้คน เขายังพูดอย่างนั้น Sheesh
MGOwen

51
upvoted ฉันเห็นด้วยอย่างยิ่งว่าไม่ควรใช้ในการผลิตแต่ฉันกำลังสร้างต้นแบบของบางสิ่งบางอย่าง เซิร์ฟเวอร์ทดสอบที่เกิดขึ้นเพื่อให้ฉันบังคับให้ฉันใช้ SSL การทำงานกับใบรับรองนั้นค่อนข้างใหม่สำหรับฉันดังนั้นฉันแค่ต้องการทางที่รวดเร็วซึ่ง imho นั้นดีเพราะฉันจะไม่ใช้มันในการผลิต
TweeZz

58

ลิงค์ที่นี่แก้ไขปัญหาของฉัน

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

ฉันไปที่ url ของเว็บเซอร์วิส (บนเซิร์ฟเวอร์ที่มีปัญหา) คลิกที่ไอคอนความปลอดภัยเล็กน้อยใน IE ซึ่งนำใบรับรองขึ้นมา จากนั้นฉันคลิกที่แท็บ Details คลิกปุ่ม Copy To File ซึ่งอนุญาตให้ฉันส่งออกหนังสือรับรองเป็นไฟล์. cer เมื่อฉันมีใบรับรองในเครื่องฉันสามารถนำเข้าใบรับรองไปยังที่เก็บใบรับรองบนเซิร์ฟเวอร์โดยใช้คำแนะนำด้านล่าง

เริ่ม MMC ใหม่ ไฟล์ -> เพิ่ม / ลบสแนปอิน ... คลิกเพิ่ม ... เลือกใบรับรองและคลิกเพิ่ม ตรวจสอบปุ่มตัวเลือก "บัญชีคอมพิวเตอร์" คลิกถัดไป

เลือกคอมพิวเตอร์ไคลเอนต์ในหน้าจอถัดไป คลิกเสร็จสิ้น คลิกปิด คลิกตกลง ตอนนี้ติดตั้งใบรับรองลงในที่เก็บใบรับรองผู้ออกใบรับรองที่เชื่อถือได้ วิธีนี้จะช่วยให้ผู้ใช้ทุกคนเชื่อถือใบรับรอง


+1 เมื่อนำเข้าใบรับรองผ่านเครื่องมือนำเข้าบนใบรับรองและไม่ผ่านสแนปอินมันเป็นเพียงสำหรับบัญชีผู้ใช้ของคุณ การใช้สแน็ปอินช่วยให้คุณเลือกได้ว่าใครจะนำเข้าบัญชีผู้ใช้บัญชีบริการหรือทุกคน ขอบคุณสำหรับตัวชี้ของคุณ ฉันเกาหัวหนึ่งหรือสองนาทีที่นั่น!
davidb

หากคุณต้องการใช้บรรทัดคำสั่งได้โดยอัตโนมัติมากกว่าเวิร์คสเตชั่ dev / ทดสอบทั้งหมด - และcertutil -f -p test -importPFX Root devcert.pfx certutil -f -p test -importPFX MY devcert.pfxจำเป็นต้องเรียกใช้ในพรอมต์คำสั่งของผู้ดูแลระบบ (สมมติว่ารหัสผ่าน PFX คือtest)
DeepSpace101

นี่เป็นวิธีที่ดีที่สุดในการแก้ไขหากคุณใช้ใบรับรองแบบลงนามด้วยตนเองสำหรับการทดสอบขอบคุณ T-Rex!
ToastyMallows

36

คุณสามารถปรับปรุงรหัสได้โดยถามผู้ใช้เมื่อใบรับรองไม่ถูกต้องว่าเขาต้องการดำเนินการต่อหรือไม่ คุณต้องการทำต่อไปหรือไม่? ดังต่อไปนี้:

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

50
ใครจะคลิกปุ่ม "ดำเนินการต่อ" หากนี่เป็นแอพคลาวด์
Konstantin Isaev

34

สายไปงานเลี้ยงเล็ก ๆ น้อย ๆ แต่ถ้าคุณกำลังมองหาวิธีการแก้ปัญหาเช่น 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;
  }
}

1
สำหรับกรณีของฉัน sslPolicyErrors คือ RemoteCertificateNameMismatch และฉันแก้ไขการตรวจสอบใบรับรองเนื่องจากเราไม่มีค่าหัวเรื่องและผู้ออกใบรับรองเดียวกัน
Ufuk Hacıoğulları

2
X509 ใบรับรองของเซิร์ฟเวอร์ Exchange ที่ใช้เก็บสลับระหว่างหนึ่งที่ลงนามด้วยตนเองและที่เชื่อถือได้ การใช้รหัสนี้ช่วยให้ผู้ดูแลระบบเครือข่ายของฉันและฉันไม่เพียง แต่เข้าใจว่าเป็นกรณีนี้ แต่ยังแก้ไขปัญหาทั้งหมดด้วยการข้ามใบรับรองที่ลงนามด้วยตนเองเท่านั้น มันสมบูรณ์แบบ!
Bret

20

ฉันมีปัญหาเดียวกันแน่นอนและพบว่าโดยค่าเริ่มต้นMail Shieldจากโปรแกรมป้องกันไวรัส Avast เปิดใช้งาน"การเชื่อมต่อสแกน SSL" ตรวจสอบให้แน่ใจว่าได้ปิดแล้ว

จากความรู้ของฉัน Avast จะ"เปิด"เมลสแกนหาไวรัสแล้วลงนามโดยใช้ใบรับรองของตัวเองเพื่อที่ว่าจดหมายนั้นจะไม่ถูกลงชื่อด้วยใบรับรองของ gmail อีกต่อไปซึ่งจะทำให้เกิดข้อผิดพลาดนั้น

โซลูชันที่ 1:

  • ปิดการสแกน SSL จากโปรแกรมป้องกันไวรัสของคุณ (หรือเกราะป้องกันจดหมายทั้งหมด)

โซลูชันที่ 2 (ควรเป็นคำพูดที่ปลอดภัยที่สุด):

  • รับใบรับรองที่ใช้โดยโปรแกรมป้องกันไวรัส (Avast มีตัวเลือกในการส่งออก)
  • นำเข้าในไคลเอนต์ imap / pop / smtp ของคุณก่อนเชื่อมต่อกับเซิร์ฟเวอร์ gmail

1
คุณช่วยฉันเวลามาก จะใช้เวลาตลอดไปคิดออกว่าโปรแกรมป้องกันไวรัสของฉันจะตำหนิและไม่ใช่รหัสของฉัน
arao6

13

รับข้อผิดพลาดเดียวกันขณะที่ส่งจาก outlook เนื่องจาก ssl 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")
                };

3
gmail จะไม่อนุญาตให้คุณเชื่อมต่อในขณะที่คุณตั้งค่า SSL เป็นเท็จฉันได้ลองวิธีการแก้ปัญหาของคุณมันไม่ได้ผลสำหรับฉัน
Zeeshan Ajmal

ใช่นี่คือสิ่งที่ฉันเรียกว่า "พื้นฐาน" (เทียบกับ "ไม่มี" หรือ "ssl") ....... การตั้งค่าอีเมลเหล่านี้มีความซับซ้อนในบางครั้ง
granadaCoder

9

คุณแน่ใจหรือว่าคุณใช้ที่อยู่เซิร์ฟเวอร์ SMTP ที่ถูกต้อง?

ทั้ง smtp.google.com และ smtp.gmail.com ใช้งานได้ แต่ใบรับรอง SSL จะออกให้กับใบรับรองที่สอง


9

ฉันมีข้อผิดพลาดเดียวกันเมื่อฉันพยายามส่งอีเมลโดยใช้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);
    }

รหัสเต็มของคลาสผู้ส่งอีเมลของฉัน:

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

}


7

ฉันรู้ว่าฉันค่อนข้างช้าในเกมนี้ แต่ฉันไม่ได้เห็นคำตอบที่นี่ชี้ไปที่บันทึกของ system.diagnostics สำหรับ TLS Stream

ก่อนที่จะทำการเปลี่ยนแปลงรหัสของคุณตรวจสอบให้แน่ใจว่าคุณเข้าใจว่าปัญหาคืออะไร 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>

รันแอปพลิเคชันของคุณอีกครั้งและตรวจสอบไฟล์ 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..

เมื่อทราบว่าสาเหตุใดที่ทำให้เกิดปัญหาคุณควรสามารถแก้ไขได้หรืออย่างน้อยก็ จำกัด การค้นหาของ Google


6

ปัญหาของฉันอยู่บน Windows 2003 Server เมื่อเรียกใช้ AuthenticateAsClient การแก้ปัญหาข้างต้น (เช่นการหลีกเลี่ยงServicePointManager.ServerCertificateValidationCallback) ไม่ทำงาน

พบว่านี่เป็นข้อบกพร่องใน Windows 2003 และมีโปรแกรมแก้ไขด่วน:

"แอปพลิเคชันที่ใช้ Cryptography API ไม่สามารถตรวจสอบใบรับรอง X.509 ใน Windows Server 2003"

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

การติดตั้งโปรแกรมแก้ไขด่วนนี้สามารถแก้ไขปัญหาของฉัน


5

ปัญหาของฉันไม่ใช่ว่าฉันอ้างอิงเซิร์ฟเวอร์ด้วยที่อยู่ IP แทน URL ฉันซื้อใบรับรองที่ลงนามจาก CA เพื่อใช้ภายในเครือข่ายส่วนตัว URL ที่ระบุในใบรับรองนั้นสำคัญเมื่ออ้างอิงเซิร์ฟเวอร์ เมื่อฉันอ้างอิงเซิร์ฟเวอร์โดย URL ในใบรับรองทุกอย่างเริ่มทำงาน


คำตอบนี้สมควรที่จะได้รับสูงเพราะมันชี้ให้เห็นข้อผิดพลาดทั่วไป คน (รวมถึงตัวฉันเอง) คิดว่าจุดประสงค์ของโฮสต์นั้นใช้เพื่อค้นหาเซิร์ฟเวอร์เท่านั้น
Mojtaba

4

โฟลเดอร์เว็บไซต์ของคุณต้องการความปลอดภัยของบริการเครือข่าย โดยเฉพาะ web.config จะใช้บัญชีนี้เพื่อเข้าถึงรีจิสทรีของคุณสำหรับใบรับรอง วิธีนี้จะหยุดความต้องการเพิ่มแฮ็คในรหัสของคุณ


4

ตรวจสอบวันที่และเวลาของคอมพิวเตอร์ หากผิดให้อัปเดตเป็นเวลาปัจจุบันหรือตั้งให้อัตโนมัติเพื่อรับเวลาจากอินเทอร์เน็ต

เนื่องจากใบรับรองเชื่อมโยงกับช่วงเวลาที่กำหนดหากนาฬิกาของคุณไม่ถูกต้องคุณมีโอกาสที่จะได้รับข้อผิดพลาดเช่นนี้ ในสถานการณ์นั้นโดยการแก้ไขเวลาปัญหาจะได้รับการแก้ไข


1
หากวันที่ระบบของคุณคือ "ไกลเกินไป" จากเวลาปัจจุบันความถูกต้องของใบรับรองที่ได้รับจาก google ทำให้เกิดปัญหา มันเห็นออกและถูกต้องกับข้อมูลที่ไม่มากเวลาปัจจุบัน นี่ไม่ใช่สิ่งเดียวที่ไม่สามารถทำให้เกิดปัญหานี้ได้ แต่มันก็เป็นหนึ่งที่สามารถ
ฟิล soady

1
คำเตือนที่มีประโยชน์อย่างมหาศาลในการตรวจสอบในกรณีของฉัน มีดโกนของอ็อกคัมและทุกอย่าง ... :) ตอนนี้เกี่ยวกับแบตเตอรี่ CMOS นั่น ...
Mike G

2

สำหรับผู้ที่พบข้อผิดพลาดเดียวกันนี้เมื่อเชื่อมต่อกับไซต์ในพื้นที่ที่มีใบรับรองแบบลงนามด้วยตนเองโพสต์บล็อกต่อไปนี้ช่วยฉันได้

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


2

ในกรณีที่ปัญหาของเราเกิดจากใบรับรองเซิร์ฟเวอร์ IIS หัวเรื่องของใบรับรองถูกตั้งค่าเป็นชื่อ DNS และผู้ใช้พยายามเข้าถึงเว็บไซต์โดยใช้ที่อยู่ IP ดังนั้นการตรวจสอบความถูกต้องของการรับรอง. NET จึงล้มเหลว ปัญหาหายไปเมื่อผู้ใช้เริ่มใช้ชื่อ DNS

ดังนั้นคุณต้องเปลี่ยน URL ผู้ให้บริการของคุณเป็นhttps: //CertificateSubject/xxx/xxx.application


คุณสามารถอธิบายรายละเอียดนี้ได้หรือไม่ ในกรณีที่แอพของฉันทำงานบนเซิร์ฟเวอร์หนึ่งและไม่ทำงานบนเซิร์ฟเวอร์อื่น ฉัน clueless ... ฉันไม่ใช่ผู้เชี่ยวชาญ แต่โดเมนยังคงเชื่อมต่อกับโดเมนที่ใช้งานได้และใบรับรองเซิร์ฟเวอร์ได้รับการติดตั้งแล้วในทั้งสองเครื่อง ยังไม่เข้าใจว่าทำไมจึงมีความเกี่ยวข้องอย่างใดอย่างหนึ่งเนื่องจากระบุว่า "ใบรับรองระยะไกล"
Michael Brennt

2

มีบทความบล็อกของ MSDN ในการตรวจสอบปัญหาประเภทนี้:

การแก้ไขปัญหา ASP.NET - ใบรับรองระยะไกลไม่ถูกต้องตามขั้นตอนการตรวจสอบความถูกต้อง:
http://blogs.msdn.com/b/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate- เป็น-ที่ไม่ถูกต้องตาม--to-การตรวจสอบ-procedure.aspx


1

การเพิ่มบรรทัดนี้ใช้งานได้สำหรับฉัน นี้ในความเป็นจริงการลงทุนใบรับรองทั้งหมดตามที่กล่าวไว้ที่นี่ อย่างไรก็ตามสิ่งนี้สามารถใช้เป็นหลักในการแก้ไขปัญหา ถ้าสิ่งนี้ใช้ได้กับคุณนั่นหมายความว่าจะไม่เพิ่มใบรับรองของเซิร์ฟเวอร์ระยะไกลเป็นใบรับรองที่เชื่อถือได้ในเครื่องของคุณ

System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);

รหัสเต็มคือ

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

0

มันแก้ไขปัญหาของฉัน

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

// ด้วยการอ้างอิงถึง // ปัญหาเกิดขึ้นเท่านั้นใช้บรรทัดด้านบนเพื่อตั้งค่า SSl false เพื่อแก้ไขข้อผิดพลาดเมื่อป้อนชื่อผู้ใช้และรหัสผ่านในการตั้งค่า SMTP


13
นี่คือการปิดการรักษาความปลอดภัย
Zoey

0

นี่คือทางออกที่ฉันตัดสินใจใช้

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

0

รหัสจากคำตอบที่ยอมรับได้ช่วยให้ฉันแก้ปัญหาได้ จากนั้นฉันก็รู้ว่าฟิลด์ SN ของการcertificateโต้แย้งนั้นไม่เหมือนกับที่ฉันคิดว่าเป็นเซิร์ฟเวอร์ SMTP ของฉัน ด้วยการตั้งค่าHostคุณสมบัติของอินสแตนซ์ SmtpClient เป็นค่า SN ของใบรับรองฉันสามารถแก้ไขปัญหาได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.