Qual é a diferença entre X509Certificate2 e X509Certificate em .NET?

Respostas:

104

O x509Certificate foi introduzido no .NET v1.0 / 1.1 e era (comparativamente) limitado em sua funcionalidade. Ele pode ser usado para obter informações sobre um certificado existente (datas de validade, emissor, etc.). Ele tinha métodos / operações simples (ou seja, ler um certificado do disco).

O x509Certificate2 é uma subclasse de x509Certificate com funcionalidade adicional.

  • Ele representa um certificado X509 real.
  • Era novo no .NET Framework v2.0.
  • Esta classe fornece acesso a todas as propriedades V2 e V3 (identificador de chave de autoridade e uso de chave).
  • Ele suporta o carregamento de um certificado de um armazenamento de certificados.
p.campbell
fonte
12
X509Certificate2também tem um membro para a chave privada, que não faz parte do próprio certificado, mas é conveniente ter associado à classe que representa o certificado X.509.
Bruno
21

Para completar, aqui está uma cópia da seção relevante do site com link na resposta de @dommer, já que o site pode não estar mais ativo e apenas no cache do Google por sabe-se lá quanto tempo:

A versão 1.1 da estrutura tinha muito pouco além da classe X509Certificate para permitir que você manipulasse certificados. Na verdade, a classe v1.1 X509Certificate deu apenas suporte básico: ela só deu acesso aos campos da versão 1 do X509 (como datas de e válidas para datas, assunto e chave pública), mas não aos campos da versão 2 (como o identificador de chave de autoridade ) nem campos da versão 3 (como o uso da chave). Não houve suporte para carregar um certificado de um armazenamento de certificados, nem tem os recursos para acessar listas de revogação de certificados ou listas de certificados confiáveis. A Microsoft aprimorou isso com o kit de ferramentas Web Services Enhancement (WSE), estendendo a classe de certificado e fornecendo classes para acessar armazenamentos de certificados. Essas classes agora podem ser encontradas na biblioteca do framework .NET 3.0 / 2.0.

A primeira grande mudança é uma nova classe chamada X509Certificate2 que deriva de X509Certificate. Os métodos para acessar os campos do certificado X509 foram descontinuados e agora a classe tem propriedades para acessar esses campos. Além disso, se o certificado tiver uma chave privada associada, a classe dará acesso a essa chave. Existem métodos que permitem que você forneça uma senha se a chave privada for protegida por uma. A senha é passada através de um parâmetro SecureString que é um tipo especial que garante que quando o objeto não estiver mais sendo usado, a memória ocupada será sobrescrita para que a senha não possa ser lida por outro processo na máquina. Strings seguras e outras formas de dados protegidos serão abordadas em uma seção posterior.

Como X509Certificate2 deriva de X509Certificate, isso significa que você pode chamar os métodos estáticos CreateFromeCertFile e CreateFromSignedFile por meio da classe X509Certificate2. No entanto, esses métodos retornam um objeto X509Certificate e você não pode fazer down cast para um objeto X509Certificate2. A classe X509Certificate foi aprimorada na versão 3.0 / 2.0: ela fornece propriedades para acessar alguns dos campos X509; fornece métodos de importação e exportação para inicializar um objeto de uma matriz de bytes ou gerar uma matriz de bytes do certificado e tem construtores que criarão um objeto a partir de um arquivo (ASN.1 DER) e de uma matriz de bytes. Curiosamente, a classe X509Certificate2 tem um construtor que pode criar um objeto X509Certificate2 a partir de um objeto X509Certificate.

Tantos goblins
fonte
6

Para converter um certificado X.509 de "X509Certificate" para "X509Certificate2", tente algo assim:

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

Para aqueles que gostariam de ler o certificado e usá-lo para autenticar, basta criar um X509Certificate2 e passar o X509Certificate em seu construtor.

Para um assembly assinado (o exe), o código seria um código como este, e omito a validação de erro para simplificar.

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, sua classe não é chamada de MyClass, mas algum objeto de negócios que você esperaria de um serviço da web.

Você pode enviar uma aula para sua ação enviando a propriedade e o valor que você deseja preenchido. Agora você pode garantir que a solicitação recebida é de um cliente móvel ou Windows válido lendo o certificado de solicitação da seguinte forma:

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
   }

}

O que resta é configurar seu servidor web para aceitar certificados de cliente ... Você pode ler tudo sobre as propriedades que vêm do novo formato e você protegeu seu serviço público da web, algo que a maioria não consegue fazer porque apenas ser autorizado não é bom o suficiente mais (se alguma vez foi)

Walter Vehoeven
fonte