2009-07-27 6 views
5

사용자가 서버에 대한 실제 인증서를 만들지 못하게하지만 보안 검사를하고 싶습니다. 그래서 다음은 너무 가볍습니다. 내가 읽었을 때, 인증서를 확인했기 때문입니다..Net 프로그래밍 : SSL 자체 서명 인증서에서 유효성을 검사 할 대상

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

클라이언트가 x509 인증서를 확인하도록 권유하고 싶은 점이 있다면 무엇입니까? .NET 언어 (C#/f #)를 사용하고 있습니다.

답변

4

클라이언트가 실제 인증서를 만들지 못하면 최소한 서버를 사용하여 인증서를 만들어야합니다. 그런 다음 CA가 손상되었는지 알 수 있기 때문에 인증서가 유효한지 또는 적어도 CA에서 확인 할 수 있습니다. 모든 CA를 신뢰하는 경우 실제로 확인할 가치가 없습니다.

+0

+1 완전히 동의 ValidateRemoteCertificate 기능에 자신의 유효성 검사 논리를 넣을 수 있습니다. 발급 CA를 신뢰할 수 없다면 나머지 인증서는 거의 무의미합니다. 진짜 * certs를 사용할 수 없다면 Spencer는 자신이 소유 한 CA를 설정하거나 (이미 가지고 있음) 신뢰할 수 있고 거기에서 사용자에게 인증서를 발급 할 수 있는지 확인합니다. –

+0

예, 이것은 좋지 않은 상황이지만 덜 복잡하게 만들려고합니다. 적어도 인증서의 이름이 지정된 URL과 일치하는지 확인합니다. – telesphore4

5

자체 서명 된 인증서를 사용하는 경우 예상되는 유일한 오류는 루트 (인증서 발급자)의 체인 오류입니다. 나는이 체인 오류에 대한 함정을 구체적으로 지적하고 다른 모든 오류가 빠지게 할 것을 제안합니다. 당신이 인증서 표시를 확인할 수있는 경우

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
    ValidateRemoteCertificate 
); 

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) 
{ 
    string trustedIssuer = "CN=www.domain.com"; 
    string trustedDomain = "CN=www.domain.com"; 
    bool policyErr = false; 

    switch (policyErrors) 
    { 
     case SslPolicyErrors.None: 
      policyErr |= false; 
      break; 
     case SslPolicyErrors.RemoteCertificateChainErrors: 
      bool chainErr = false; 
      foreach (X509ChainStatus status in chain.ChainStatus) 
      { 
       switch (status.Status) 
       { 
        case X509ChainStatusFlags.NoError: 
         chainErr |= false; 
         break; 
        case X509ChainStatusFlags.UntrustedRoot: 
         if (certificate.Subject != trustedDomain || certificate.Issuer != trustedIssuer) 
          chainErr |= true; 
         else 
          chainErr |= false; 
         break; 
        default: 
         chainErr |= true; 
         break; 
       }      
      } 
      policyErr |= chainErr; 
      break; 
     default: 
      policyErr |= true; 
      break; 
    } 

    return !policyErr; 
} 
1

당신은

System.Net.ServicePointManager.ServerCertificateValidationCallback += (a, b, c, d) => 
{ 
    return ValidateRemoteCertificate(a, b, c, d); 
}; 

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, 
      X509Chain chain, SslPolicyErrors policyErrors) 
{ 
      if (certificate.Subject.Equals("CN=www.domain.com")) 
       return true; 
      else 
       return policyErrors == SslPolicyErrors.None; 

} 
+0

제발하지 마세요. 이것은 보안의 환상을 제공하지만 아무 것도 가지고 있지 않기 때문에 아무 것도없는 것보다 더 나쁩니다. 어느 누구나 쉽게 "CN = www.domain.com"문자열을 사용하여 인증서를 만들 수 있습니다. – Daryl

관련 문제