¿Cuál es la diferencia entre X509Certificate2 y X509Certificate en .NET?


Respuestas:


106

El certificado x509 se introdujo en .NET v1.0 / 1.1 y estaba (comparativamente) limitado en su funcionalidad. Se puede utilizar para obtener información sobre un certificado existente (fechas válidas, emisor, etc.). Tenía métodos / operaciones simples (es decir, leer un certificado desde el disco).

El X509Certificate2 es una subclase de X509Certificate con funcionalidad adicional.

  • Representa un certificado X509 real.
  • Era nuevo en .NET Framework v2.0.
  • Esta clase le da acceso a todas las propiedades V2 y V3 (identificador de clave de autoridad y uso de clave).
  • Admite cargar un certificado desde un almacén de certificados.

12
X509Certificate2también tiene un miembro para la clave privada, que no es parte del certificado en sí, pero es conveniente tenerlo asociado con la clase que representa el certificado X.509.
Bruno

21

En aras de la integridad, aquí hay una copia de la sección relevante del sitio vinculado en la respuesta de @ dommer, ya que es posible que el sitio ya no esté activo y solo en la caché de Google durante quién sabe cuánto tiempo:

La versión 1.1 del marco tenía muy poco más que la clase X509Certificate para permitirle manipular certificados. De hecho, la clase v1.1 X509Certificate solo brindó soporte básico: solo dio acceso a los campos de la versión 1 de X509 (como las fechas válidas desde y hasta las fechas, el asunto y la clave pública) pero no los campos de la versión 2 (como el identificador de la clave de autoridad) ) ni los campos de la versión 3 (como el uso de claves). No había soporte para cargar un certificado desde un almacén de certificados, ni tiene las facilidades para acceder a listas de revocación de certificados o listas de confianza de certificados. Microsoft mejoró esto con el kit de herramientas de mejora de servicios web (WSE) que amplía la clase de certificado y proporciona clases para acceder a los almacenes de certificados. Estas clases ahora se pueden encontrar en la biblioteca del marco .NET 3.0 / 2.0.

El primer gran cambio es una nueva clase llamada X509Certificate2 que se deriva de X509Certificate. Los métodos para acceder a los campos del certificado X509 han quedado obsoletos y ahora la clase tiene propiedades para acceder a esos campos. Además, si el certificado tiene una clave privada asociada, la clase da acceso a esta clave. Existen métodos que le permiten proporcionar una contraseña si la clave privada está protegida por una. La contraseña se pasa a través de un parámetro SecureString, que es un tipo especial que asegura que cuando el objeto ya no se use, la memoria que ocupaba se escribirá para que otro proceso no pueda leer la contraseña en la máquina. Las cadenas seguras y otras formas de datos protegidos se tratarán en una sección posterior.

Dado que X509Certificate2 se deriva de X509Certificate, significa que puede llamar a los métodos estáticos CreateFromeCertFile y CreateFromSignedFile a través de la clase X509Certificate2. Sin embargo, estos métodos devuelven un objeto X509Certificate y no puede convertirlo en un objeto X509Certificate2. La clase X509Certificate se ha mejorado en la versión 3.0 / 2.0: proporciona propiedades para acceder a algunos de los campos X509; proporciona métodos de importación y exportación para inicializar un objeto a partir de una matriz de bytes o generar una matriz de bytes a partir del certificado y tiene constructores que crearán un objeto a partir de un archivo (ASN.1 DER) y de una matriz de bytes. Curiosamente, la clase X509Certificate2 tiene un constructor que puede crear un objeto X509Certificate2 a partir de un objeto X509Certificate.


6

Para convertir un certificado X.509 de "X509Certificate" a "X509Certificate2", intente algo como esto:

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

2

Para aquellos que deseen leer el certificado y usarlo para autenticarse, simplemente crearán un X509Certificate2 y pasarán el X509Certificate en su constructor.

Para un ensamblado firmado (el exe), el código sería un código como este, y omito la validación de errores por simplicidad.

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

Obviamente, su clase no se llama MyClass sino un objeto comercial que esperaría del servicio web.

Puede enviar una clase a su acción enviando la propiedad y el valor que necesita. Ahora puede asegurarse de que la solicitud que recibió es de un cliente móvil o de Windows válido leyendo el certificado de solicitud de la siguiente manera:

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
   }

}

Lo que queda es configurar su servidor web para que acepte certificados de cliente ... Puede leer todo sobre las propiedades que provienen del nuevo formato y ha asegurado su servicio web público, algo que la mayoría no logra, ya que solo estar autorizado no es suficiente más (si alguna vez lo fue)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.