2009-07-27 14 views
5

Nie mogę uzyskać od użytkowników autentycznych certyfikatów dla ich serwerów, ale chciałbym przeprowadzić pewne kontrole bezpieczeństwa. Tak więc poniższe jest zbyt lekkie, ponieważ, gdy je czytam, jest nie sprawdzanie certyfikatów.. Programowanie w sieci .NET: co należy sprawdzić na certyfikacie z podpisem własnym SSL

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

Co zaleca się, aby klienci sprawdzili certyfikat x509? Biorąc pod uwagę, że używam języka .NET (C#/f #).

Odpowiedz

4

Jeśli nie możesz poprosić klientów o utworzenie prawdziwych certyfikatów, powinieneś przynajmniej spróbować przekonać ich do tworzenia certyfikatów za pomocą serwera. Następnie możesz sprawdzić, czy certyfikat jest ważny lub przynajmniej od twojego urzędu certyfikacji, ponieważ dowiesz się, czy Twój urząd certyfikacji został naruszony. Jeśli ufasz wszystkim CA, naprawdę nie ma nic wartego sprawdzenia.

+0

+1 zgadzam całkowicie. O ile nie można ufać wystawiającemu CA, to reszta certyfikatu jest prawie bez znaczenia. Jeśli nie możesz użyć * prawdziwych * certyfikatów, to jak mówi Spencer, sprawdź, czy możesz skonfigurować (lub już posiadasz) swój własny ośrodek certyfikacji, któremu możesz zaufać i wydać certyfikaty swoim użytkownikom. –

+0

Tak, to jest zła sytuacja, ale staram się ją zmniejszyć. Przynajmniej sprawdzę, czy nazwa w certyfikacie jest zgodna z podanym adresem URL. – telesphore4

5

Jeśli używasz samopodpisanych certyfikatów, jedynymi błędami, których należy się spodziewać, jest błąd łańcucha w katalogu głównym (wystawcy certyfikatu). Sugerowałbym coś takiego, że pułapki na konkretny błąd łańcucha i pozwala, aby wszystkie inne błędy wpadły.

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

jeśli można sprawdzić certyfikatów można umieścić swoją własną logikę walidacji w funkcji ValidateRemoteCertificate

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

Nie rób tego. To jest gorsze niż nic, ponieważ zapewnia iluzję bezpieczeństwa, ale nie ma jej wcale. Każdy może trywialnie utworzyć certyfikat z łańcuchem "CN = www.domena.com" w nim. – Daryl

Powiązane problemy