В чем разница между X509Certificate2 и X509Certificate в .NET?

Ответы:

106

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

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

  • Он представляет собой настоящий сертификат X509.
  • Это было новостью в .NET Framework v2.0.
  • Этот класс дает вам доступ ко всем свойствам V2 и V3 (идентификатор ключа доступа и использование ключа).
  • Он поддерживает загрузку сертификата из хранилища сертификатов.
П. Кэмпбелл
источник
12
X509Certificate2также имеет член для закрытого ключа, который не является частью самого сертификата, но его удобно связать с классом, представляющим сертификат X.509.
Bruno
21

Для полноты, вот копия соответствующего раздела сайта, на который есть ссылка в ответе @dommer, поскольку сайт может больше не работать и находится в кеше Google неизвестно как долго:

Версия 1.1 инфраструктуры почти не имела, кроме класса X509Certificate, чтобы вы могли управлять сертификатами. Фактически, класс X509Certificate v1.1 предоставлял только базовую поддержку: он давал доступ только к полям X509 версии 1 (например, действительным от и до дат, теме и общедоступному ключу), но не к полям версии 2 (например, идентификатору ключа доступа ), ни поля версии 3 (например, использование ключа). Не было поддержки для загрузки сертификата из хранилища сертификатов, а также не было средств для доступа к спискам отзыва сертификатов или спискам доверенных сертификатов. Microsoft улучшила это с помощью инструментария 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
   }

}

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

Уолтер Веховен
источник