У чому різниця між X509Certificate2 та X509Certificate у .NET?


Відповіді:


106

X509Certificate був введений в .NET 1.0 / 1.1 і був (порівняно) обмежений в своїй функціональності. За його допомогою можна отримати інформацію про існуючий сертифікат (дійсні дати, видачу тощо). Він мав прості методи / операції (тобто зчитування сертифіката з диска).

X509Certificate2 підклас X509Certificate з додатковими функціональними можливостями .

  • Він являє собою фактичний сертифікат X509.
  • Це було нове у .NET Framework v2.0.
  • Цей клас надає доступ до всіх властивостей V2 та V3 (ідентифікатор ключа повноваження та використання ключа).
  • Він підтримує завантаження сертифіката з магазину сертифікатів.

12
X509Certificate2також має член для приватного ключа, який не є частиною самого сертифіката, але його зручно асоціювати з класом, що представляє сертифікат X.509.
Бруно

21

Для повноти наведемо копію відповідного розділу сайту, на який посилається відповідь @ dommer, оскільки веб-сайт може більше не працювати, і лише в кеш-пам’яті Google на невідомо скільки часу:

У версії 1.1 фреймворку було дуже мало крім класу X509Certificate, що дозволяло маніпулювати сертифікатами. Насправді клас v1.1 X509Certificate надав лише базову підтримку: він надав доступ лише до полів версії 1 X509 (наприклад, дійсних від і дійсних до дат, теми та відкритого ключа), але не полів версії 2 (як ідентифікатор ключа повноважень). ), а також поля версії 3 (як використання ключа). Не вдалося завантажити сертифікат із сховища сертифікатів, а також не має засобів доступу до списків відкликання сертифікатів або списків довіри сертифікатів. Корпорація Майкрософт покращила це завдяки набору інструментів Web Services Enhancement (WSE), що розширює клас сертифікатів та надає класи для доступу до сховищ сертифікатів. Ці класи тепер можна знайти в бібліотеці фреймворків .NET 3.0 / 2.0.

Перша велика зміна - це новий клас під назвою X509Certificate2, який походить від X509Certificate. Методи доступу до полів сертифіката X509 застаріли, і тепер клас має властивості доступу до цих полів. Крім того, якщо сертифікат має пов’язаний приватний ключ, клас надає доступ до цього ключа. Існують методи, які дозволяють надати пароль, якщо закритий ключ захищений ним. Пароль передається через параметр SecureString, який є особливим типом, який гарантує, що коли об'єкт більше не використовується, пам'ять, яку він займає, буде переписана, щоб пароль не міг прочитати інший процес на машині. Захищені рядки та інші форми захищених даних будуть розглянуті в наступному розділі.

Оскільки X509Certificate2 походить від X509Certificate, це означає, що ви можете викликати статичні методи CreateFromeCertFile та CreateFromSignedFile через клас X509Certificate2. Однак ці методи повертають об'єкт X509Certificate, і ви не можете передати його в об'єкт X509Certificate2. Клас X509Certificate був вдосконалений у версії 3.0 / 2.0: він надає властивості доступу до деяких полів X509; він надає методи імпорту та експорту для ініціалізації об'єкта з байтового масиву або генерування байтового масиву із сертифіката, і він має конструктори, які створять об'єкт з файлу (ASN.1 DER) та з байтового масиву. Цікаво, що клас X509Certificate2 має конструктор, який може створити об’єкт X509Certificate2 з об’єкта X509Certificate.


6

Щоб перетворити сертифікат X.509 із "X509Certificate" в "X509Certificate2", спробуйте щось подібне:

X509Certificate  X509  = sslStream.RemoteCertificate;
X509Certificate2 X5092 = new X509Certificate2(X509);

2

Для тих, хто хотів би прочитати сертифікат і використовувати його для автентифікації, він просто створив би X509Certificate2 і передав X509Certificate в його конструктор.

Для підписаної збірки (exe) код буде таким кодом, і я пропускаю перевірку помилок для простоти.

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

Очевидно, що ваш клас називається не MyClass, а якийсь бізнес-об'єкт, якого ви очікуєте від веб-служби.

Ви можете надіслати клас до своєї дії, надіславши заповнене властивість та значення. Тепер ви можете переконатися, що отриманий вами запит надійшов від дійсного мобільного або клієнта Windows, прочитавши сертифікат запиту приблизно так:

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
   }

}

Залишилося налаштувати ваш веб-сервер на прийняття сертифікатів клієнта ... Ви можете прочитати все про властивості, які походять від нового формату, і ви захистили свою публічну веб-службу. Щось більшість не вдається зробити, оскільки просто авторизація недостатня більше (якщо це коли-небудь було)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.