Certificados Digitais em .NET – Parte 2

Neste artigo vamos nos concentrar na Geração de Certificados de Cliente completos, abordando a Cadeia de Certificação e como gerá-la. Também veremos como é o ciclo de vida de um Certificado Digital.

Artigo no estilo: Curso

Fique por dentro
Este artigo trata dos conceitos de Certificação Digital e PKI e é um tutorial para o desenvolvimento de uma Autoridade Certificadora simples, uma Autoridade de Registro, módulos de Assinatura, Validação e Criptografia usando Certificados Digitais colocando em prática os conceitos aprendidos.

Neste artigo vamos nos concentrar na Geração de Certificados de Cliente completos, abordando a Cadeia de Certificação e como gerá-la. Também veremos como é o ciclo de vida de um Certificado Digital.

Desde 2001, existe legislação específica na Constituição Brasileira que permite a autenticação de comunicações e documentos eletrônicos por meio do uso de Certificados Digitais gerados sob a Autoridade Certificadora Brasileira.

Do mesmo modo, o conceito pode ser aplicado para fortalecer as comunicações de qualquer aplicação a custo zero ou estar em acordo com a legislação vigente.

Um Certificado Digital é um invólucro digital formatado de acordo com o padrão PKCS#12 da RSA contendo em seu interior um envelope digital em formato PKCS#8 o qual mantém protegida a chave privada (quando inserida no envelope), a chave pública em formato PKCS#7 e os atributos (datas de geração e validade, assinatura da Autoridade Certificadora e os dados da mesma, pontos de distribuição da Lista de Certificados Revogados, entre outros atributos).

O Certificado Digital que usamos em nossas aplicações ou para enviar à Receita Federal nossa declaração de imposto de renda, por exemplo, partiu de uma requisição feita em formato PKCS#10, foi assinada por uma Autoridade Certificadora Intermediária que, por sua vez, teve seu Certificado assinado por uma Autoridade Certificadora Raiz.

Deste modo, quando abrimos nosso Certificado Digital temos certeza de que todo o processo de geração foi validado por mais de uma entidade confiável e em sua estrutura há todos os meios necessários para garantir o uso de seu par de chaves.

Cadeia de Certificação

A Cadeia de Certificação é uma estrutura hierárquica que permite demonstrar quais entidades de Certificação foram participantes da geração de um Certificado Digital. Quando abrimos um Certificado completo, conforme a Figura 1, podemos verificar esta hierarquia.

Figura 1. Cadeia de Certificação

No exemplo apresentado vemos que existe uma Autoridade Certificadora Raiz confiável no sistema operacional e que abaixo dela existe uma Autoridade Certificadora Intermediária pronta para gerar certificados sob sua hierarquia.

Geração de Certificado Raiz

Na aplicação que começamos a desenvolver na primeira parte desta série de artigos temos uma opção de menu que nos permitiu gerar o par de chaves para a Autoridade Certificadora Raiz. Agora vamos codificar a opção que nos permita gerar um Certificado Digital Raiz para esta Autoridade Certificadora.

Este Certificado Raiz vai permitir assinar a requisição da Autoridade Certificadora Intermediária e dar subsídios para que ela possa gerar tantos Certificados de Cliente quantos necessários.

No seu projeto, abra o Designer do Form1 e no menu “Autoridade Certificadora Raiz”> opção “Gerar Certificado Raiz”, dê um duplo clique e coloque o código da Listagem 1.

Listagem 1. Chamada ao formulário de Geração de Certificado Raiz. 01 private void gerarCertificadoRaizToolStripMenuItem_Click(object sender, EventArgs e) 02 { 03 NovoCertificado nc = new NovoCertificado(); 04 nc.ShowDialog(); 05 }

Este Form foi descrito em nosso artigo anterior. O código do botão Salvar irá gerar uma Requisição de Certificado Digital em formato PKCS#10.

Em seguida, precisamos inserir, para a opção “Assinar Requisição de Autoridade Intermediária” do menu “Autoridade Certificadora Raiz”, o código da Listagem 2.

Listagem 2. Assinando a requisição de Certificado de Autoridade Intermediária 01 private void assinarRequisiçãoDeAutoridadeIntermediáriaToolStripMenuItem_Click (object sender, EventArgs e) 02 { 03 try 04 { 05 CertificationRequestInfo csrInfo = null; 06 RsaKeyParameters pubKeyParameters = null; 07 Pkcs10CertificationRequest csr = null; 08 OpenFileDialog dialog = new OpenFileDialog(); 09 dialog.Filter = "Requisição de Certificado (*.csr)|*.csr"; 10 dialog.FilterIndex = 1; 11 12 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 13 { 14 TextReader reader = new StreamReader(dialog.FileName); 15 PemReader pReader = new PemReader(reader); 16 17 csr = (Pkcs10CertificationRequest)pReader.ReadObject(); 18 csrInfo = csr.GetCertificationRequestInfo(); 19 SubjectPublicKeyInfo pubKeyInfo = csrInfo.SubjectPublicKeyInfo; 20 RsaPublicKeyStructure pubKeyStructure = RsaPublicKeyStructure.GetInstance(pubKeyInfo.GetPublicKey()); 21 pubKeyParameters = new RsaKeyParameters (false, pubKeyStructure.Modulus, pubKeyStructure.PublicExponent); 22 bool certificadoOK = csr.Verify(pubKeyParameters); 23 } 24 25 Org.BouncyCastle.X509.X509Certificate certificadoRaiz = null; 26 27 dialog = new OpenFileDialog(); 28 dialog.Filter = "Certificado Raiz (*.cer)|*.cer"; 29 dialog.FilterIndex = 1; 30 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 31 { 32 certificadoRaiz = DotNetUtilities.FromX509Certificate (System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile (dialog.FileName)); 33 } 34 35 AsymmetricKeyParameter chavePrivadaRaiz = null; 36 dialog = new OpenFileDialog(); 37 dialog.Filter = "Chave Privada Raiz (*.pvk)|*.pvk"; 38 dialog.FilterIndex = 1; 39 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 40 { 41 var bytesChave = Convert.FromBase64String (File.ReadAllText(dialog.FileName).Replace ("-----BEGIN RSA PRIVATE KEY-----\r\n", "").Replace ("-----END RSA PRIVATE KEY-----", "")); 42 AsymmetricCipherKeyPair pair; 43 using (var reader = File.OpenText(dialog.FileName)) 44 { 45 pair = (AsymmetricCipherKeyPair) new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject(); 46 chavePrivadaRaiz = pair.Private; 47 } 48 } 49 50 X509V3CertificateGenerator gerador = new X509V3CertificateGenerator(); 51 gerador.SetSerialNumber(BigInteger.ProbablePrime(120, new Random())); 52 gerador.SetIssuerDN(certificadoRaiz.SubjectDN); 53 gerador.SetNotBefore(DateTime.Now); 54 gerador.SetNotAfter(DateTime.Now.AddYears(5)); 55 gerador.SetSubjectDN(csrInfo.Subject); 56 gerador.SetPublicKey(pubKeyParameters); 57 gerador.SetSignatureAlgorithm("SHA1WithRSA"); 58 gerador.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); 59 gerador.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, new AuthorityKeyIdentifierStructure(certificadoRaiz)); 60 gerador.AddExtension(X509Extensions.SubjectKeyIdentifier, true, new SubjectKeyIdentifierStructure(pubKeyParameters)); 61 gerador.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment)); 62 gerador.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)); 63 64 var novoCertificadoIntermediario = gerador.Generate(chavePrivadaRaiz); 65 66 SaveFileDialog salvaDialog = new SaveFileDialog(); 67 salvaDialog.Filter = "Certificado Intermediario (*.p12)|*.p12"; 68 salvaDialog.FilterIndex = 1; 69 if (salvaDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 70 { 71 Pkcs12Store store = new Pkcs12Store(); 72 store.SetCertificateEntry("Intermediaria", new X509CertificateEntry(novoCertificadoIntermediario)); 73 74 X509CertificateEntry[] cadeia = new X509CertificateEntry[1]; 75 cadeia[0] = new X509CertificateEntry(certificadoRaiz); 76 77 store.SetKeyEntry("Chave Privada", new AsymmetricKeyEntry(GetChavePrivada ("Chave Privada Intermediária (*.pvk)|*.pvk")), cadeia); 78 79 string senha = Microsoft.VisualBasic.Interaction.InputBox ("Digite sua senha", "ATENÇÃO", "", 0, 0); 80 MemoryStream s = new MemoryStream(); 81 store.Save(s, senha.ToCharArray(), new SecureRandom()); 82 byte[] bytesPkcs = s.GetBuffer(); 83 bytesPkcs = Pkcs12Utilities.ConvertToDefiniteLength (bytesPkcs, senha.ToCharArray()); 84 BinaryWriter bw = new BinaryWriter(File.Open (salvaDialog.FileName, FileMode.Create)); 85 bw.Write(bytesPkcs); 86 bw.Close(); 87 MessageBox.Show("Certificado Intermediário Salvo com Sucesso", "ATENÇÃO", MessageBoxButtons.OK, MessageBoxIcon.Information); 88 } 89 } 90 catch (Exception ex) 91 { 92 MessageBox.Show("Algo deu errado", "ATENÇÃO", MessageBoxButtons.OK, MessageBoxIcon.Error); 93 } 94 }"

[...] continue lendo...
Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados