Jaka jest różnica między X509Certificate2 i X509Certificate w .NET?

Odpowiedzi:

106

X509Certificate wprowadzono NET v1.0 / 1.1 i był (stosunkowo) ogranicza jego funkcjonalności. Można go wykorzystać do uzyskania informacji o istniejącym certyfikacie (ważne daty, wystawca itp.). Miał proste metody / operacje (np. Odczyt certyfikatu z dysku).

X509Certificate2 jest podklasą x509Certificate z dodatkową funkcjonalnością.

  • Stanowi rzeczywisty certyfikat X509.
  • To było nowe w .NET Framework v2.0.
  • Ta klasa zapewnia dostęp do wszystkich właściwości V2 i V3 (identyfikator klucza urzędu i użycie klucza).
  • Obsługuje ładowanie certyfikatu z magazynu certyfikatów.
p.campbell
źródło
12
X509Certificate2ma również członka klucza prywatnego, który nie jest częścią samego certyfikatu, ale wygodnie jest go powiązać z klasą reprezentującą certyfikat X.509.
Bruno,
21

Dla zachowania kompletności, poniżej znajduje się kopia odpowiedniej sekcji witryny, do której link znajduje się w odpowiedzi @ dommer, ponieważ witryna może już nie działać i może znajdować się tylko w pamięci podręcznej Google, kto wie jak długo:

Wersja 1.1 tego frameworka zawierała niewiele więcej niż klasa X509Certificate, aby umożliwić manipulowanie certyfikatami. W rzeczywistości klasa X509Certificate w wersji 1.1 zapewniała tylko podstawowe wsparcie: dawała dostęp tylko do pól X509 w wersji 1 (takich jak ważne od i ważne do dat, tematu i klucza publicznego), ale nie zapewniała dostępu do pól wersji 2 (takich jak identyfikator klucza urzędu ) ani pól wersji 3 (jak użycie klucza). Nie było możliwości ładowania certyfikatu z magazynu certyfikatów, nie ma też możliwości dostępu do list odwołania certyfikatów ani list zaufania certyfikatów. Microsoft ulepszył to dzięki zestawowi narzędzi Web Services Enhancement (WSE) rozszerzającym klasę certyfikatów i udostępniającym klasy dostępu do magazynów certyfikatów. Te klasy można teraz znaleźć w bibliotece platformy .NET 3.0 / 2.0.

Pierwsza duża zmiana to nowa klasa o nazwie X509Certificate2, która pochodzi od X509Certificate. Metody uzyskiwania dostępu do pól certyfikatu X509 zostały wycofane i teraz klasa ma właściwości umożliwiające dostęp do tych pól. Ponadto, jeśli certyfikat ma powiązany klucz prywatny, wówczas klasa daje dostęp do tego klucza. Istnieją metody, które pozwalają podać hasło, jeśli klucz prywatny jest chroniony. Hasło jest przekazywane przez parametr SecureString, który jest specjalnym typem, który zapewnia, że ​​gdy obiekt nie jest już używany, zajmowana przez niego pamięć zostanie nadpisana, aby hasło nie mogło zostać odczytane przez inny proces na komputerze. Bezpieczne łańcuchy i inne formy chronionych danych zostaną omówione w dalszej części.

Ponieważ X509Certificate2 pochodzi od X509Certificate, oznacza to, że można wywołać statyczne metody CreateFromeCertFile i CreateFromSignedFile za pośrednictwem klasy X509Certificate2. Jednak te metody zwracają obiekt X509Certificate i nie można go rzutować na obiekt X509Certificate2. Klasa X509Certificate została ulepszona w wersji 3.0 / 2.0: zapewnia właściwości umożliwiające dostęp do niektórych pól X509; zapewnia metody importu i eksportu do inicjowania obiektu z tablicy bajtów lub generowania tablicy bajtów z certyfikatu i ma konstruktory, które utworzą obiekt z pliku (ASN.1 DER) i z tablicy bajtów. Co ciekawe, klasa X509Certificate2 ma konstruktora, który może utworzyć obiekt X509Certificate2 z obiektu X509Certificate.

Tak wiele goblinów
źródło
6

Aby przekonwertować certyfikat X.509 z „X509Certificate” na „X509Certificate2”, wypróbuj coś takiego:

X509Certificate  X509  = sslStream.RemoteCertificate;
X509Certificate2 X5092 = new X509Certificate2(X509);
ftexperts
źródło
2

Dla tych, którzy chcieliby odczytać certyfikat i użyć go do uwierzytelnienia, wystarczy utworzyć X509Certificate2 i przekazać X509Certificate w jego konstruktorze.

W przypadku podpisanego zestawu (exe) kod byłby taki jak ten, a dla uproszczenia pomijam sprawdzanie poprawności błędów.

Module m = Assembly.GetEntryAssembly().GetModules()[0];
using (var cert = m.GetSignerCertificate())
using (var cert2 = new X509Certificate2(cert))
{
   var _clientHandler = new HttpClientHandler();
   _clientHandler.ClientCertificates.Add(cert2);
   _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
   var myModel = new Dictionary<string, string>
   {
       { "property1","value" },
       { "property2","value" },
   };
   using (var content = new FormUrlEncodedContent(myModel))
   using (var _client = new HttpClient(_clientHandler))
   using (HttpResponseMessage response = _client.PostAsync($"{url}/{controler}/{action}", content).Result)
   {
       response.EnsureSuccessStatusCode();
       string jsonString = response.Content.ReadAsStringAsync().Result;
       var json = new Newtonsoft.Json.JsonSerializer();
       var myClass = JsonConvert.DeserializeObject<MyClass>(json);
    }
}

Oczywiście Twoja klasa nie nazywa się MyClass, ale jest obiektem biznesowym, którego można oczekiwać od usługi internetowej.

Możesz wysłać klasę do swojego działania, wysyłając wypełnioną właściwość i wartość. Możesz teraz upewnić się, że otrzymane żądanie pochodzi od prawidłowego klienta mobilnego lub Windows, czytając certyfikat żądania w następujący sposób:

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {           
       X509Certificate2 clientCertInRequest = Request.HttpContext.Connection.ClientCertificate;
       if (!clientCertInRequest.Verify() || !AllowedCerialNumbers(clientCertInRequest.SerialNumber))
       {
            Response.StatusCode = 404;
            return null;
       }
       //your code
   }

}

Pozostaje tylko ustawić serwer WWW tak, aby akceptował certyfikaty klienta ... Możesz przeczytać wszystko o właściwościach, które pochodzą z nowego formatu i zabezpieczyłeś swoją publiczną usługę sieciową. już (jeśli kiedykolwiek był)

Walter Vehoeven
źródło