[C#] “원격 인증서가 유효성 검사 절차에 따라 유효하지 않습니다.” Gmail SMTP 서버 사용

이 오류가 발생합니다.

유효성 검사 절차에 따라 원격 인증서가 유효하지 않습니다.

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)



답변

경고 : 프로덕션 코드에서는 이것을 사용하지 마십시오!

이 문제를 해결하려면 인증서 유효성 검사를 해제 할 수 있습니다. 인증서가 잘못되어 오류가 발생했다는 확인을 얻기 위해이 작업을 수행해야합니다.

전화하기 전에이 메소드를 호출하십시오 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

웹 서비스 (문제가있는 서버의) URL로 이동하여 IE의 작은 보안 아이콘을 클릭하여 인증서를 가져 왔습니다. 그런 다음 세부 정보 탭을 클릭하고 파일로 복사 버튼을 클릭하여 인증서를 .cer 파일로 내보낼 수있었습니다. 인증서를 로컬로 가져 오면 아래 지침을 사용하여 인증서를 서버의 인증서 저장소로 가져올 수있었습니다.

새 MMC를 시작하십시오. 파일-> 스냅인 추가 / 제거 … 추가 …를 클릭하십시오. 인증서를 선택하고 추가를 클릭하십시오. “컴퓨터 계정”라디오 버튼을 확인하십시오. 다음을 클릭하십시오.

다음 화면에서 클라이언트 컴퓨터를 선택하십시오. Finish를 클릭하십시오. 닫기를 클릭하십시오. 확인을 클릭하십시오. 이제 신뢰할 수있는 루트 인증 기관 인증서 저장소에 인증서를 설치하십시오. 이렇게하면 모든 사용자가 인증서를 신뢰할 수 있습니다.


답변

인증서가 유효하지 않은 경우 사용자에게 계속하고 싶은지 묻는 메시지를 표시하여 코드를 개선 할 수 있습니다. 계속 하시겠습니까? 아래:

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의 솔루션과 같은 솔루션을 찾고 있다면 다음 코드를 사용하여 문제가 자체 서명 인증서와 관련이 있는지 확인하고 자체 서명 오류를 무시하십시오. 원하는 경우 다른 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;
  }
}


답변

나는 똑같은 문제가 있었고 기본적으로 Avast 바이러스 백신 의 Mail Shield“Scan SSL connection”이 활성화되어 있음을 알았습니다 . 반드시 끄십시오 .

내가 아는 바에 따르면, Avast는 메일을 “열고” 바이러스를 검사 한 다음 자체 인증서를 사용하여 서명하여 더 이상 gmail의 인증서로 메일에 서명하지 않으므로 해당 오류가 발생하지 않습니다.

해결책 1 :

  • 안티 바이러스 (또는 전체 메일 쉴드)에서 SSL 스캔을 끕니다.

해결 방법 2 (최상의 보안 기능이어야 함) :

  • 바이러스 백신이 사용하는 인증서를 가져옵니다 (Avast에는 인증서를 내보낼 수있는 옵션이 있음)
  • Gmail 서버에 연결하기 전에 imap / pop / smtp 클라이언트에서 가져 오십시오.

답변

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


답변

올바른 SMTP 서버 주소를 사용하고 있습니까?

smtp.google.com과 smtp.gmail.com은 모두 작동하지만 SSL 인증서는 두 번째 인증서에 발급됩니다.