it-roy-ru.com

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

Какая разница между двумя?

70
Kyle

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

x509Certificate2 является подклассом x509Certificate с дополнительными функциями. 

  • Он представляет собой действительный сертификат X509. 
  • Это было новым в .NET Framework v2.0.
  • Этот класс дает вам доступ ко всем свойствам V2 и V3 (идентификатор ключа авторизации и использование ключа). 
  • Он поддерживает загрузку сертификата из хранилища сертификатов.
84
p.campbell

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

Версия 1.1 фреймворка имела очень мало другого, кроме X509Сертификат класса, позволяющий вам манипулировать сертификатами. В Фактически, класс X509Certificate версии 1.1 дал только базовую поддержку: только предоставил доступ к полям X509 версии 1 (например, действительным с и действительным для дат, субъекта и открытого ключа), но не к полям версии 2 (например, идентификатору ключа доступа) или полям версии 3 (например, к ключу) использование). Не было поддержки для загрузки сертификата из сертификата магазин, и при этом у него нет средств для доступа к сертификату списки отзыва или списки доверия сертификатов. Microsoft улучшила это с помощью инструментария Web Services Enhancement (WSE), расширяющего класс сертификата и предоставление классов для доступа к хранилищам сертификатов . Эти классы теперь можно найти в библиотеке фреймворков .NET 3.0/2.0.

Первое большое изменение - это новый класс под названием X509Certificate2, который происходит от сертификата X509. Методы доступа к X509 поля сертификата устарели, и теперь класс имеет свойства для доступа к этим полям. Кроме того, если сертификат имеет соответствующий закрытый ключ, тогда класс дает доступ к этому ключу . Существуют методы, которые позволяют вам предоставить пароль, если частный Ключ защищен одним. Пароль передается через SecureString параметр, который является специальным типом, который гарантирует, что, когда объект больше не используется, память, которую он занимал, будет перезаписана, поэтому что пароль не может быть прочитан другим процессом на машине . Защищенные строки и другие формы защищенных данных будут рассмотрены в позже раздел.

Поскольку X509Certificate2 происходит от X509Certificate, это означает, что вы может вызывать статические методы CreateFromeCertFile и CreateFromSignedFile с помощью класса X509Certificate2. Тем не мение, эти методы возвращают объект X509Certificate, и вы не можете выключить приведите это к объекту X509Certificate2. Класс X509Certificate имеет был улучшен в версии 3.0/2.0: он предоставляет свойства для доступа некоторые из полей X509; он предоставляет методы импорта и экспорта в инициализировать объект из байтового массива или генерировать байтовый массив из сертификат и у него есть конструкторы, которые будут создавать объект из файла (ASN.1 DER) и из байтового массива. Интересно, что Класс X509Certificate2 имеет конструктор, который может создавать Объект X509Certificate2 из объекта X509Certificate. Обратите внимание, что хотя объект X509Certificate может отображать только поля X509v1 может быть создан из сертификата X509v3 и так, если вы создаете X509Certificate2 объект из объекта X509Certificate вы будете возможность доступа к полям X509v3.

18
So Many Goblins

Чтобы преобразовать сертификат X.509 из «X509Certificate» в «X509Certificate2», попробуйте что-то вроде этого:

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

Для тех, кто хотел бы прочитать сертификат и использовать его для аутентификации, просто создайте 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
   }

}

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

0