Mestrado em Informática - ALFA

Transcrição

Mestrado em Informática - ALFA
UNIVERSIDADE DO MINHO
Mestrado em Informática
Desenvolvimento
de PKIs em Java
MESTRADO EM INFORMÁTICA
Desenvolvimento de PKIs em Java
Pedro Miguel Félix Alípio
[email protected]
Índice
1. Introdução
1
2. Conceitos Básicos
2
2.1 Criptografia de Chave Secreta
2
2.2 Criptografia de Chave Pública
2
2.3 Assinaturas Digitais
3
2.4 Funções de Hash
3. Requisitos de uma PKI
3
4
3.1 Introdução
4
3.2 Requisitos Obrigatórios
4
3.2.1 Principais Funcionalidades
4
Criação de Autoridades de Certificação
4
Iniciação de Subscritores
4
Registo e Certificação
5
Publicação de Certificados
5
Anulação de Certificados
6
Publicação de CRLs
6
Mudança do Equipamento dos Subscritores
6
Comunicações
6
Software pré-existente
6
Normalizações pré-existentes
6
Autorização de Acessos
7
Escalabilidade
7
Robustez e tolerância a falhas
7
Auditorias
7
3.3 Requisitos Opcionais
8
Adaptabilidade
8
Facilidade de implementação
8
Gestão distribuída dos componentes da PKI
8
Compatibilidade de Normas
8
Interoperabilidade com outros sistemas
9
Recuperação de Chaves
9
Desempenho
9
4. O Java Criptográfico
10
4.1 Avalanche
10
Algoritmos criptográficos
10
Funções de hash
10
Classes utilitárias
10
Plataforma
10
Números Aleatórios
11
4.2 BeeJCE e BeeCrypt
11
4.3 ABA JCE
12
Algoritmos de cifragem
12
Algoritmos de Message Digest
12
Licença
12
4.4 BC Crypto
12
Algoritmos
12
4.5 IAIK
13
Algoritmos
13
Implementação do JCE
14
ASN.1
14
PKCS
14
X509
14
Geração de Números Aleatórios
15
4.5 JCSI
15
JCE
15
PKI
15
TLS
15
Mensagens Criptográficas
16
S/MIME
16
Kerberos
16
Licença
5. Funcionalidades de uma PKI e respectiva implementação em Java
16
17
5.1 Introdução
17
5.1 Subscritor
17
5.1.1 Iniciar Pedido de Certificado
17
5.1.2 Gerar par de chaves
18
Criar um gerador de pares de chaves
18
Iniciar o gerador de pares de chaves
18
Gerar o par de chaves
19
5.1.3 Criar pedido de certificado
19
Construtores
19
Métodos
20
Envio do pedido de certificado
20
5.1.4 Iniciar pedido de actualização de chaves
21
1
Determinar o final do ciclo de vida de uma chave
21
Gerar pedido de actualização de chaves
21
Obter um objecto para assinatura
21
Iniciar o objecto de assinatura
22
Envio do pedido de actualização de chaves
22
5.1.5 Instalar chave privada
22
Guardar a chave privada
22
Ler a chave privada
23
5.1.6 Prova de posse de chave privada
23
5.1.7 Instalar e guardar certificados
23
5.1.8 Assinar e decifrar com a chave privada
24
5.1.9 Apresentar o certificado aos outros
24
5.1.10 Iniciar pedido de revogação
25
5.1.11 Iniciar pedido extensão do prazo de validade
25
5.2 Autoridade de Registo
25
5.2.1 Verificar a identidade do subscritor
26
5.2.2 Aprovar ou modificar o conteúdo do certificado
26
O campo attributes do PKCS#10
26
5.2.3 Gerar pares de chaves
26
5.2.4 Guardar pares de chaves
27
5.2.5 Distribuição de tokens
27
5.2.6 Testes de posse de chave privada
27
Obter chave pública
28
Iniciar objecto de assinatura
28
Assinar a mensagem
28
Verificar a assinatura
28
5.2.7 Atribuição de DN e modificação do conteúdo do certificado
5.3 Autoridade de Certificação
28
29
5.3.1 Responder a pedidos de renovação de certificados
29
5.3.2 Modificar ou aprovar modificações do conteúdo do certificado
29
5.3.3 Iniciar e aprovar revogação
30
5.3.4 Criar certificado raiz auto assinado
30
Gerar um certificado a partir de um par de chaves
30
Gerar um certificado CA auto assinado com o JCSI
30
5.3.5 Emissão de certificados
30
5.3.6 Disponibilizar os certificados aos subscritores
31
5.3.7 Publicação dos certificados
32
5.3.8 Revogar certificados (Adicionar à CRL)
32
5.3.9 Publicar CRL
33
5.3.10 Pedido de Certificação Cruzada
33
5.3.11 Aceitar Certificação Cruzada
33
5.4 Repositório de Certificados
34
5.4.1 Armazenar certificados e CRLs
34
5.4.2 Disponibilizar Certificados e CRLs
34
2
5.4.3 Verificar o estado do Certificado
34
5.5 Aplicações ou Utilizadores
35
5.5.1 Receber certificados
35
5.5.2 Pedir Certificados
35
5.5.3 Validar Certificado
35
5.5.4 Verificar identidades e Assinaturas
36
5.5.5 Cifrar com o Certificado
6. Conclusão
36
37
7. Referências
38
Implementação de um CA de domínio público
38
APIs Criptográficos
38
LDAP
38
SSL
38
PKI em geral
39
3
1. Introdução
Introdução ás infra-estruturas de chave publica
Com o rápido crescimento da Internet e o seu alargamento a todos os sectores da sociedade,
nomeadamente às áreas de negócios, foi surgindo a necessidade de implementar sistemas que fossem capazes de
garantir privacidade e autenticidade nas comunicações. Como se sabe a Internet é uma rede insegura onde as
comunicações estão sujeitas a intercepções, monitorizações e adulterações. O conceito de privacidade consiste
na transmissão de mensagens que não possam ser alteradas nem lidas durante a sua transmissão. O conceito de
autenticidade consiste em garantir que cada um dos intervenientes envolvidos na comunicação tenham a certeza
da identidade dos outros, o que implica que as mensagens não podem ser adulteradas. A ciência capaz de dar
resposta a estes problemas e criar soluções para garantir estas duas propriedades nas comunicações chama-se
Criptografia. Esta ciência disponibiliza meios para que duas pessoas, normalmente apelidadas de Alice e Bob,
possam comunicar abertamente sem que uma terceira pessoa, normalmente apelidada de Oscar, seja capaz de
saber o conteúdo da comunicação. Assegurando a privacidade, a Criptografia garante indirectamente a
autenticidade porque apenas a Alice e o Bob sabem encriptar e decifrar as mensagens dum e do outro.
A criptografia de chave pública é a técnica criptográfica que melhor encaixa na Internet. Cada utilizador
de um sistema destes tem um par de chaves. Uma mensagem é encriptada com uma das chaves e pode ser
decifrada com a outra. Uma das chaves permanece secreta enquanto a outra é publicada. Esta técnica permite que
se possam enviar mensagens encriptadas com a chave publica e apenas a pessoa que detém a chave privada as
possa ler. Desta forma garante-se a privacidade na comunicação. Para que seja garantida a autenticidade basta que
a mensagem seja assinada com a chave secreta. Se os destinatários aplicaram a chave publica do emissor podem
certificar-se que a mensagem é efectivamente autentica.
Para que todo o processo de atribuição e publicação das chaves públicas fosse credível, foram criadas as
infra-estruturas de chaves públicas (PKI).
Com este trabalho, em primeiro lugar, pretendo identificar as principais funcionalidades e características
que uma infra-estrutura de chave publica deve possuir. De seguida pretendo identificar os packages de Java de que
implementem funcionalidades criptográficas que possam ser usadas na implementação destas infra-estruturas.
Finalmente pretendo explicar de que forma se podem aplicar alguns desses packages na implementação em cada
componente de uma PKI.
1
2. Conceitos Básicos
Conceitos e técnicas criptográficas básicas
2.1 Criptografia de Chave Secreta
A criptografia de chave secreta é forma mais clássica de criptografia. Esta técnica já é utilizada desde
tempos muito remotos. Num sistema de chave secreta, ambas as partes partilham um segredo, que consiste na
chave de cifragem e decifragem da mensagem. Este sistema obriga a trocas de mensagens entre o emissor e o
receptor de forma a negociarem uma chave. O mais famoso algoritmo de chave secreta é o DES (Data Encryption
Standard). Hoje em dia é frequente usar uma evolução deste algoritmo chamado Triple-DES.
Existem sistemas para comunicação segura sobre redes públicas que usam este tipo de criptografia. Um
dos mais conhecidos é o Kerberos. A grande desvantagem deste tipo de sistemas é que não são facilmente
escaláveis a populações inter-organizacionais de grande dimensão, e exigem procedimentos de segurança
suplementares que os sistemas de chaves públicas não necessitam, como por exemplo, guardar as chaves secretas
num servidor central de segurança.
2.2 Criptografia de Chave Pública
A criptografia de chave pública é uma técnica criptográfica bastante recente. Foi desenvolvida em 1976
por Diffie e Hellman. Em 1977, Rivest, Shamir e Adleman criaram a primeira implementação de um sistema de chave
publica, ao qual chamaram de RSA Cryptosystem. Ao longo do tempo foram surgindo novos sistemas como o
ElGamal ou o Sistema da Curva Elíptica.
Cada sistema de chave pública tem particularidades técnicas distintas, no entanto todos partilham o
conceito de que, dada uma chave de cifragem não se pode a partir desta obter a chave de decifragem e vice-versa.
Este conceito permite que um utilizador possa publicar uma chave (chave pública), toda a gente que desejar
enviar mensagens a esse utilizador podem cifrar as mensagens com essa chave. Apenas esse utilizador poderá ler
as mensagens pois é o único a deter a chave capaz de as decifrar (chave privada).
O facto de o desempenho de um sistema deste tipo ser mais lento que um sistema de chave secreta,
levou a que se utilizassem sistemas de chave pública para o transporte da chave privada, por exemplo, enviar uma
mensagem cifrada usando um sistema de chave secreta DES, e a chave secreta ser enviada usando um sistema de
chave pública RSA, isto é, o sistema de chave pública transporta a chave privada. Tendo em conta que a chave
privada é bastante mais pequena que a mensagem, esta técnica resulta em bastante mais rapidez de
processamento que usando apenas um sistema de chave pública.
2
2.3 Assinaturas Digitais
A criptografia de chave pública permite a “assinatura digital” de mensagens. Se um indivíduo publicar a
chave de decifragem e manter secreta a chave de cifragem, e se enviar mensagens cifradas, todos os receptores
usando a chave publicada podem certificar-se que apenas esse individuo poderia ser o emissor. Pode dizer-se que
o emissor “assinou” as mensagens.
Em alguns sistemas de chave pública, como por exemplo o RSA, tanto a chave pública como a chave
privada, podem ser usadas para cifrar e decifrar. Isto permite que um par de chaves possa ser usado
simultaneamente para cifragem de mensagens e assinatura digital. Esta prática pode no entanto levantar vários
problemas no que diz respeito à gestão do par de chaves.
Se o par de chaves for usado para assinatura digital, a chave privada não pode ser guardada, e deve ser
destruída no fim do seu ciclo de vida. Se a chave for descoberta pode vir a ser usada para forjar documentos. Se
isso acontecer depois do seu ciclo de vida, continua ser possível forjar assinaturas em documentos antigos.
Se o par de chaves for usado para garantir privacidade a chave privada deve ser guardada durante o maior
tempo possível, porque caso a chave privada seja perdida, será impossível ler as mensagens cifradas com a chave
pública.
Tendo em conta que para as duas funções têm requisitos contraditórios, o melhor será então usar dois
pares de chaves.
2.4 Funções de Hash
Normalmente para assinar mensagens usam-se funções de hash em vez da criptografia de chave pública.
Uma função de hash criptográfica mapeia uma mensagem de tamanho variável a um número fixo de bits. As
funções de hash têm as seguintes propriedades:
•
Não produzem colisões. Isto é, duas mensagens distintas nunca produzem o mesmo valor.
•
Só têm um sentido. Isto é, a partir de um determinado valor não é possível produzir uma
qualquer mensagem que produza esse valor.
Estas funções são também designadas de Message Digest ou algoritmos de fingerprint. Os mais conhecidos
são o MD5 e o SH-1.
Para assinar uma mensagem são necessários dois passos. Em primeiro lugar aplica-se a função de hash à
mensagem, depois o resultado e cifrado usando um sistema de chave pública. A mensagem é depois transmitida
juntamente com os seu hash cifrado. Para verificar a assinatura, o receptor aplica a função de hash à mensagem, se
o valor obtido for igual ao valor de hash cifrado temos a garantia que a mensagem não foi adulterada.
3
3. Requisitos de uma PKI
Descrição dos principais requisitos uma PKI.
3.1 Introdução
Os requisitos podem dividir-se em dois tipos: Obrigatórios e opcionais. Os requisitos obrigatórios
são aqueles que são comuns a todas as soluções e são necessários para que essas soluções sejam
consideradas viáveis. Os requisitos opcionais são mais valias, isto é, são desejados mas não obrigatórios.
São um factor fundamental na escolha da melhor solução.
Os principais objectivos de uma PKI é a emissão de certificados de chave pública para que seja
assegurada a autenticação, privacidade, integridade e autorização para determinadas aplicações críticas.
Uma implementação de uma infra-estrutura deste tipo deverá ter vários tipos de componentes,
nomeadamente tecnológicos, humanos, políticos e procedimentais. Existem várias alternativas na
implementação de PKIs. Muitas dessas alternativas passam pela integração de vários produtos
preenchendo assim todos requisitos.
3.2 Requisitos Obrigatórios
3.2.1 Principais Funcionalidades
A solução de PKI deve implementar todos as funções e processos que são necessários
para que de forma segura e credível sejam criados, distribuídos, e geridos os certificados de chave
pública para as entidades-fim (subscritores).
Criação de Autoridades de Certificação
A solução de PKI deve disponibilizar a criação de Autoridades de Certificação (CA)
que possam emitir, certificar, e gerir certificados.
Iniciação de Subscritores
A solução de PKI deve disponibilizar a possibilidade de iniciar os subscritores na PKI.
Devem ser disponibilizados certificados CA-raiz e outros detalhes para que o subscritor tome
consciência da PKI e use os serviços de segurança que esta disponibiliza.
4
Registo e Certificação
A solução de PKI deve assegurar a emissão e assinatura de certificados. Passa isso deve
possuir as seguintes funções:
Pedido de registo /certificação inicial. A solução de PKI tem de possibilitar que
os subscritores possam iniciar um pedido de um certificado e enviar esse pedido de
forma segura à Autoridade de Registo (RA) e/ou à Autoridade de Certificação. A
solução de PKI tem de permitir que os subscritores criem um par de chaves
pública-privada. Depois, deve ser criado um Pedido de Certificado de Assinatura
contendo a chave pública para que o pedido seja enviado de forma segura à RA
e/ou à CA.
Registo. A solução de PKI tem de permitir a validação da identidade de um
subscritor pela RA e/ou CA e associar essa identidade a um determinado pedido
de certificado. A RA e/ou a CA têm de ter a capacidade de requerer ao subscritor
uma prova de posse, para que seja assegurado que esse subscritor realmente possui
e controla a chave privada correspondente à chave pública do certificado a ser
enviado.
Envio de certificados. A solução de PKI tem de permitir que a RA e/ou a CA
possam emitir certificados contendo informação determinada por elas próprias, isto
é a informação que os certificados contêm pode ser alterada podendo ser diferente
da que foi pedida pelo subscritor no Pedido de Certificado de Assinatura. Os
certificados devem poder ser assinados pela(s) CA(s) definidas.
Actualização de pares de chaves das CAs. A solução de PKI tem de permitir que
as chaves das CAs possam ser actualizadas e que os certificados das CAs sejam
reenviados.
Certificação cruzada. A solução de PKI tem de permitir o estabelecimento de
acordos de certificação cruzada com outras CAs
Actualização de certificação cruzada. Os certificados cruzados devem poder ser
refrescados.
Publicação de Certificados
A solução de PKI tem de permitir que os certificados sejam publicados em repositórios
de forma a que as entidades que contam com os certificados possam verificar as suas
validades e as entidades que requererem a chave publica de um subscritor para cifrar uma
sessão ou uma mensagem, possam obte-la através desse repositório.
Para além disto, a solução de PKI devem também disponibilizar a possibilidade de se
enviarem certificados ao subscritor para instalação no seu software (Servidores web,
Browsers, Clientes de e-mail, etc...) ou para os subscritores adquirirem os certificados (por
exemplo via HTTP) para depois os instalarem.
5
Anulação de Certificados
A solução de PKI tem de permitir processar pedidos de anulação de determinados
certificados por parte dos administradores e por parte dos subscritores.
Publicação de CRLs
A solução de PKI tem de permitir a publicação e distribuição das Listas de Certificados
Anulados (CRL) para que as entidades que contam com eles possam ser informadas que esses
certificados foram anulados.
Mudança do Equipamento dos Subscritores
A solução de PKI tem responder às mudanças do software e harware dos subscritores.
Para isso deve implementar as seguintes funções:
Mover um par de chaves para a nova máquina, enquanto se retém o mesmo
certificado que liga este par de chaves a um subscritor particular. É aceitável
mas não desejável o reenvio do certificado quando o hardware é alterado.
Mudar o mecanismo de protecção que é usado para proteger a imagem
guardada da chave privada. É aceitável a regeneração do par de chaves quando
o mecanismo de protecção for alterado.
Comunicações
As comunicações entre os subscritores, gestores, e os componentes da PKI devem
ser efectuadas utilizando os canais de comunicação existentes (Rede local, Wan, Internet,
etc...) de forma segura.
Software pré-existente
A solução de PKI tem de ser capaz de gerir certificados de acordo com os
formatos e normalizações que existem nas versões actuais do software já existente
(Navigator, Explorer, etc...).
Normalizações pré-existentes
A solução de PKI tem de poder publicar certificados numa estrutura de directório
acessível. Por exemplo o LDAP (Lightweight Directory Access Protocol).
6
Autorização de Acessos
Deve ser implementada uma Autoridade de Autorização de Acessos (AAA) através da
qual administradores distribuídos poderão criar e gerir a autorização de acesso nos directórios
LDAP. As entradas de um directório LDAP que são usadas para conter os certificados
poderão ser usadas para conterem informação relativa à autorização do acesso. A solução de
PKI não deve impor restrições ao formato no directório LDAP, que possam de alguma
forma criar conflitos ou obstruir o armazenamento da informação da autorização.
A autorização de acessos pode ser armazenada fora da estrutura de certificados para
facilitar a separação entre emissão de certificados (CA/RA) e a autorização de acessos (AAA),
não sendo necessária a implementação de funções de autorização dentro da solução PKI.
No entanto existe uma relação de dependência entre a solução de PKI e a AAA. A
AAA usará certificados para assinar a entradas de autorizações para que seja mantida a sua
integridade.
Escalabilidade
A solução de PKI deve ser escalável relativamente ao número de subscritores, deve
permitir administração humana distribuída, deve suportar tipos de certificados distintos
enviados segundo distintas políticas (as aplicações e os recursos podem ter políticas de
certificados distintas e/ou diferentes propósitos para o uso dos certificados).
Robustez e tolerância a falhas
A solução de PKI deve possuir mecanismos ou características que garantam a
continuidade do funcionamento da solução, isto é, deve ser estável e deve “correr”
continuamente sem que seja necessária intervenção manual regular (por exemplo reboots). A
solução de PKI deve recuperar de falhas nos seus componentes. No caso de uma falha em
larga escala nunca poderá resultar numa situação de insegurança (por exemplo acessos a
pessoas não autorizadas).
Auditorias
A solução de PKI deve permitir a auditoria das suas principais funções. Deve ser
escrito um log com o registo da actividade da PKI. Deve também ser implementada a
capacidade de reconstruir o estado de um certificado a partir de um qualquer tempo no
passado. O acesso aos logs deve ser restrito.
7
3.3 Requisitos Opcionais
Adaptabilidade
A solução de PKI poderá possuir a capacidade de se adaptar a novas políticas de
certificados, a novos usos para os certificados e a novos algoritmos criptográficos.
Facilidade de implementação
A solução de PKI deve ser fácil de implementar.
Gestão distribuída dos componentes da PKI
A solução de PKI deve suportar a separação opcional dos papeis de CA e RA. A
solução de PKI deve suportar vários utilizadores como administradores CA ou RA.
A solução de PKI deve suportar a administração distribuída do repositório LDAP de
certificados (CR) para que a responsabilidade de autorização possa ser distribuída a vários
utilizadores actuando como AAA.
Compatibilidade de Normas
A solução de PKI deverá emitir e gerir certificados de acordo com as normas
existentes:
O repositório de certificados deverá ser publicado numa estrutura de directório
acessível pelo LDAP.
Os certificados devem respeitar a norma X509v3 e suportar extensões locais. As
soluções que utilizem Browsers sem serem modificados deverão suportar as
extensões do Netscape e Explorer.
A gestão de certificados para a interoperabilidade com outras PKIs deve respeitar as
normas de IETF PKIX Working Group.
A solução PKI deverá suportar o JCE.
A solução PKI deverá disponibilizar a capacidade de emitir e gerir certificados para
serem usados clientes de e-mail com S/MIME.
A solução de PKI não deve disponibilizar serviços através de métodos proprietários
ou extensões proprietárias.
8
Interoperabilidade com outros sistemas
A solução de PKI deverá poder interoperar com outros componentes de segurança
existentes, por exemplo com o Kerberos/DCE, com Objectos assinados, IPsec, etc...
Recuperação de Chaves
A solução de PKI deverá permitir opcionalmente a recuperação de pares de chaves que
tenham sido perdidos ou ficado corrompidos, ou cujo mecanismo de protecção já não seja
detido ou conhecido pelo subscritor. Esta funcionalidade pode ser bastante importante, pois
informação cifrada que se tenha tornado inacessível pela perda ou corrupção de chaves,
poderá desta forma ser novamente acedida pelo subscritor.
Desempenho
A solução de PKI deverá ser capaz de desempenhar todas as funções em tempo útil
gastando o mínimo possível de recursos de computação ou largura de banda de
comunicações.
9
4. O Java Criptográfico
Estudo dos principais packages criptográficos de Java.
4.1 Avalanche
Algoritmos criptográficos
DES, Triple-DES, Blowfish, TEA, e cifras de blocos de 3 vias
CBC, CFB, OFB, e ECB
Todos os modos suportados para todas as cifras de blocos
Pike stream cipher, disponibiliza rápida cifragem de dados e uma segura geração de números
aleatórios.
“Fast DES” opcional que não efectua permutações iniciais nem finais
Funções de hash
MD2, MD5, e SHA-1
HMAC para autenticação de dados
Classes utilitárias
Cifragem, autenticação e hashing de streams de input e output
O protocolo de stream cifrado usa o PKCS#5
As streams podem ser seguras contra ataques activos e monitorização passiva
Conversão de frase chave para chave.
Plataforma
Java puro, totalmente portável
JDK 1.0 e JDK 1.1
10
Números Aleatórios
Geração segura de números pseudo-aleatórios para suporte dos algoritmos criptográficos
Sistema multi-fonte de medida de entropia
A entropia pode ser introduzida no gerador quando este fica disponível
4.2 BeeJCE e BeeCrypt
É uma implementação do JCE (Java Cyptographic Extension). Foi desenvolvido porque o JCE
não pode ser exportado dos E.U.A (as últimas versões beta podem mas só segundo determinadas
condições). O BeeJCE está disponível sob uma licença GNU (Lesser General Public License) que pode
ser usado livremente e grátis para aplicações comerciais. O código fonte encontra-se também
disponível. O BeeJCE pode ser usado juntamente com o BeeCrypt for Java que consiste numa
biblioteca criptográfica e num JCE 1.2 cryptographic service provider.
O BeeCrypt contém :
Fontes de entropia para inicializar a geração de números pseudo-aleatórios
Geradores de números pseudo-aleatórios : FIPS-186, Mersenne Twister
Cifras de blocos: Blowfish
Funções de hash: SHA-1
Funções de hash com chaves: SHA-1/HMAC
Biblioteca de números inteiros de precisão variável, com rotinas
implementadas em Assembler para optimização.
Teste probabilistico de primos
Geração de parâmetros logarítmico discretos sobre um campo de um primo
Acordo de chaves Diffie-Hellman
Duas variantes do ElGamal para assinaturas.
11
4.3 ABA JCE
É uma implementação do JCE (Java Cyptographic Extension). Foi desenvolvido porque o JCE
não pode ser exportado dos E.U.A tal como BeeJCE. O objectivo desta implementação é ser o mais
fiel possível à implementação da Sun Microsystems.
Algoritmos de cifragem
O ABA cryptographic provider disponibiliza os seguintes algoritmos de cifragem: DES,
DESede (ou "triple DES"), IDEATM, RC4®, Blowfish, Twofish e RSA. Existem geradores de
chaves para todos os algoritmos.
Algoritmos de Message Digest
Algoritmos de Message Digest: SHA-0, SHA-1, e MD5.
Licença
Licença de domínio público e código fonte disponível.
4.4 BC Crypto
O package Bouncy Castle Crypto é mais uma implementação de um pacote criptográfico em Java.
Esta implementação está em conformidade com o JCE. Possui uma licença do tipo MIT X
Consortium. O BC Crypto as seguintes características:
É uma implementação do JCE.
Tem suporte para : Cifras de blocos, Cifras de blocos com buffers, Cifras de blocos
assimétricas, Cifras de blocos assimétricas com buffers, Cifras de
12
Digest: MD2, MD5, RipeMD160, SHA-1.
MAC: CBCBlockCipherMac, CFBBlockCipherMac, Hmac..
PBE: PKCS5S1ParametersGenerator, PKCS5S2ParametersGenerator,
PKCS12ParameterGenerator.
Acordo de chaves: Duas versões do Diffie-Hellman, em que uma é a básica e outra
para chaves de longo prazo.
ASN.1 : Uma API com interface directo sobre um package capaz de ler e escrever na
codificação DER para geração de certificados X509v3. Também está
implementado BER InputStream.
BC Provider : Compatível com o JCE.
4.5 IAIK
Também o IAIK é uma alternativa ao JCE dadas as restrições à suaeaçoçsriud
13
Implementação do JCE
Cifras: DES, DESede, IDEA, Blowfish, GOST, CAST128, RC2, RC4, RC5, RSA
(PKCS#1), PbeWithMD5AndDES_CBC (PKCS#5),
PbeWithSHAAnd3_KeyTripleDES (PKCS#12), PbeWithSHAAnd40BitRC2_CBC
(PKCS#12)
Fábricas de chave secreta: DES, DESede, PBE (PKCS#5), PKCS#12
Algoritmos de acordos de chaves: DH (PKCS#3)
MACs: HMAC/MD5, HMAC/SHA
Geradores de chaves: DES, DESede, IDEA, Blowfish, GOST, CAST128, RC2, RC4,
RC5, RSA, PKCS#12, PKCS#12-IV, PKCS#12-MAC, PBKDF2 (PKCS#5 ver 2)
Modos : ECB, CBC, PCBC, CFB, OFB, 0 1 e 2 para RSA (PKCS#1)
Padding: PKCS5Padding, SSL3Padding, PKCS1Padding
ASN.1
ASN.1 (Abstract Syntax Notation One)
Definido na norma ISO 8824/ITU X.208 que especifica uma linguagem para
descrever estruturas de dados de uma forma abstracta e independente da
plataforma. O IAIK suporta os tipos de dados: BOOLEAN, INTEGER,
BITSTRING, OCTETSTRING, NULL, OBJECTIDENTIFIER,
ENUMERATED, SEQUENCE, SET, SEQUENCE OF, SET OF, UTCTime,
etc…
Utilitários para codificação e descodificação para DER, Base64, e PEM para que
estruturas ASN.1 possam ser implementadas como classes de Java.
PKCS
PKCS#1 – Norma criptográfica RSA
PKCS#5 – Norma de cifragem baseada em palavra-chave.
PKCS#7 – Norma do sintaxe de mensagens criptográficas.
PKCS#8 – Norma do sintaxe de informação sobre chaves privadas.
PKCS#10 – Norma do sintaxe do pedido de certificado.
PKCS#12 – Norma do sintaxe de troca de informação pessoal.
X509
14
O IAIK suporta todas as extensões da norma x509v3, extensões CRL da norma
x509v2 e também as extensões de certificados da Netscape.
X509v3: AuthorityKeyIdentifier, BasicConstraints, CertificatePolicies, CRLDistributionPoints,
IssuerAltName, KeyUsage, NameContraints, PolicyConstraints, PolicyMappings,
PrivateKeyUsagePeriod, SubjectAltName, SubjectKeyIdentifier.
CRL X509v2: CRLNumber, ReasonCode.
Extenções de certificados Netscape: NetscapeBaseUrl, NetscapeCaPolicyUrl,
NetscapeCaRevogationUrl, NetscapeCertRenewalUrl, NetscapeCertType, NetscapeComment,
NetscapeRevocationUrl, NetscapeSSLServerName
Geração de Números Aleatórios
O IAIK possui vários geradores de números aleatórios.
4.5 JCSI
O JCSI inclui:
JCE
Uma implementação do JCE compatível com o JCE 1.2
Um security provider para o JCA/JCE para:
Chave Pública: RSA, DSA, Diffie-Hellman.
Cifras: IDEA, DESede, Blowfish, RC5, RC4, RC2 e DES
PKI
Uma biblioteca para desenvolvimento de PKI
Fornecedor de fábrica de certificados x509v3 e v2 CRLs
PKCS#12 – Armazenagem de chaves
Uma API para PKCS#10 – Pedidos de certificados
Uma API para PKCS#8 e protecção de chaves privadas tipo SSLeavy
Uma API para geração de certificados x509 e CRLs que podem ser usada
para construir ferramentas para uma CA.
TLS
Uma biblioteca que implementa uma camada de transporte segura (TLS)
Suporte para SSLv3 e TLS
15
Suporta todos os conjuntos de cifras não anónimas baseadas em RSA ou
Diffie-Hellman
Implementa a API JESSE
Mensagens Criptográficas
Uma biblioteca para sintaxe de mensagens criptográficas
Suporta CMS SignedData e EnvelopedData
Suporta RSA e DSA para assinaturas
Suporta RSA e Diffie-Hellman para cifrar
S/MIME
Uma biblioteca para suporte de S/MIME v3
Assinatura e cifragem de mensagens MIME
RSA e DSA para assinaturas e RSA para cifragem
Assinatura limpa e opaca
Incorporação no framework JavaMail
Kerberos
Uma biblioteca para o Kerberos 5
Uma API para efectuar pedidos e processar respostas de um centro de
distribuição de chaves Kerberos (KDC).
Uma API para GSS (IETF RFC2853) para mensagens ao nivel da aplicação.
Licença
Este software é gratuito para aplicações não comerciais. É possível discutir
alternativas à licença contactando DSTC Pty. Ltd, mail: [email protected].
16
5. Funcionalidades de uma PKI e
respectiva implementação em Java
Estudo das principais funcionalidades de uma infra-estrutura de chaves públicas e respectiva implementação em
Java criptográfico
5.1 Introdução
Neste capitulo irão ser descritos em detalhe os componentes fundamentais de uma Infra-estrutura
de Chave Pública, assim como que recursos de programação em Java que o JCA/JCE, assim como ouros
packages disponibilizam para a implementação de cada um desses componentes.
Tipicamente uma PKI é composta por cinco componentes básicos. Três desses componentes
podem ser considerados como o núcleo da PKI: a Autoridade de Registo (RA), a Autoridade de
Certificação (CA) e o Repositório de Certificados (CR). Os dois componentes restantes representam as
entidades que usam os certificados para impor segurança: os Subscritores (são também vulgarmente
designados por entidades-fim) e Aplicações/Utilizadores (também designados por “relying entities”).
5.1 Subscritor
O Subscritor é que possui o certificado. O objectivo dos certificados é atribuir um par de chaves a
uma identidade. A identidade pode ser um utilizador humano ou pode ser um recurso de informação
(aplicações). Na prática, o objectivo dos certificados pode ser: verificação de identidade (autenticação),
criação e verificação de assinaturas digitais, ou a troca de mensagens cifradas.
Normalmente é necessária bastante interacção entre vários utilizadores humanos (exemplo: trocas de
e-mails), entre utilizadores humanos e recursos de informação (exemplo: aplicações cliente-servidor), ou
entre vários processos computacionais (exemplo: pontos fim de VPNs). Nestes casos cada entidade
desempenha simultaneamente os papeis de subscritor e aplicação/utilizador (entidade que confia).
5.1.1 Iniciar Pedido de Certificado
Esta função representa o primeiro passo no ciclo de vida do certificado. Pode ser efectuado
por um subscritor humano, um administrador actuando em representação de um subscritor não
humano, ou por um administrador de segurança.
17
5.1.2 Gerar par de chaves
Os pares de chaves podem ser gerados por software cliente, um servidor central de segurança,
o motor criptográfico de smart cards. São geradas as chaves publicas e as chaves privadas.
É uma preocupação primária a protecção da chave privada depois de ter sido gerada. Grande
parte das implementações tentam minimizar o número de humanos que podem aceder à chave
privada. Na realidade, a chave privada geralmente nunca é vista pelo utilizador humano. Existe um
token ou palavra chave que serve para desbloquear a chave privada. Algumas aplicações dividem a
chave privada em várias partes e/ou mantêm várias cópias da chave para recuperação.
Em Java, para se gerarem par de chaves, têm de se seguir os seguintes passos:
Criar um gerador de pares de chaves
O primeiro passo é obter um gerador de pares de chaves.
Da mesma forma que para todas as classes tipo motor, para se obter um objecto
KeyPairGenerator para um determinado tipo de algoritmo, é necessário invocar o método
“fábrica” getInstance static na classe KeyPairGenerator. Existem duas formas de invocar este
método: uma apenas tem um argumento que é uma string correspondente ao algoritmo, a
outra tem um argumento adicional que consiste numa string que especifica qual o provider a
ser utilizado. Pode-se desta forma escolher um algoritmo de um qualquer provider que pode
ser o da Sun ou um dos referidos no capítulo anterior.
Vejamos um exemplo:
KeyPairGenerator keyGen =
KeyPairGenerator.getInstance("DSA", "SUN");
Iniciar o gerador de pares de chaves
O passo seguinte é iniciar o gerador de pares de chaves. Todos os geradores de
pares de chaves têm em comum os conceitos de tamanho da chave e fonte de aleatori
edade. A classe KeyPairGenerator tem um método que se chama initialize que recebe estes
dois conceitos como argumentos.
Por exemplo, para o algoritmo DSA o tamanho da chave em bits deve ser 1024.
A fonte de aleatoriedade deverá ser uma instância da classe SecureRandom. Vejamos
um exemplo em que usa o gerador de pseudo-números aleatórios SHA1PRNG
disponibilizado pela Sun. A instância da classe SecureRandom é passada ao método de
iniciação do gerador de pares de chaves.
SecureRandom random =
SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
18
A implementação de SecureRandom irá tentar ela mesma gerar um estado interno
aleatório, a não ser que seja invocado o método setSeed a seguir ao getInstance. Caso isto seja
feito, o gerador de números aleatórios irá usar a semente indicada.
Gerar o par de chaves
O passo final é i gerar o par de chaves é guarda-las nos objectos PrivateKey e
PublicKey. Vejamos:
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
5.1.3 Criar pedido de certificado
O software cliente gera um pedido de certificado que contem a identidade do subscritor e a sua
chave pública. O formato normalmente usado é o PKCS#10.
O JCA/JCE da Sun não implementa este protocolo. No entanto pode ser construída uma classe
com base na notação ASN.1 que implemente o sintaxe para pedidos de certificados segundo o PKCS#10:
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm SignatureAlgorithmIdentifier,
signature Signature }
CertificationRequestInfo ::= SEQUENCE {
version Version,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
attributes [0] IMPLICIT Attributes }
Version ::= INTEGER
Attributes ::= SET OF Attribute
SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
Signature ::= BIT STRING
O JCSI por exemplo, já tem suporte para este protocolo e implementa:
Construtores
Que geram pedidos de certificados baseando-se na codificação DER, com o
seguinte sintaxe: PKCS10CertificationRequest(byte[] encoded) ou
PKCS10CertificationRequest(InputStream is) caso a origem seja um stream.
19
Que geram pedidos de certificados a partir do DN (Distinguished Name) do
sujeito, chave pública, um conjunto de atributos, o nome do algoritmo de
assinatura e a chave privada do sujeito.
PKCS10CertificationRequest(String dn, PublicKey pub, Set atts,
String sigAlgName, PrivateKey priv)
Métodos
Um método que devolve a codificação DER do pedido de certificado.
Métodos que devolvem a chave pública, o nome do algoritmo da chave, o
nome do algoritmo de assinatura e o nome do sujeito.
Um método para verificar a assinatura.
Envio do pedido de certificado
O Envio do pedido de certificado pode ser enviado à CA de forma segura usando por
exemplo SSL. Existe uma implementação de referência em Java: o JESSE de Sun. Por exemplo o
JCSI tem um implementação deste modelo. Vejamos um exemplo:
import java.io.*;
import javax.net.ssl.*;
...
int port = availablePortNumber;
String host = "hostname";
try {
SLSocketFactory sslFact =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket s =
(SSLSocket)sslFact.createSocket(host, port);
OutputStream out = s.getOutputStream();
InputStream in = s.getInputStream();
// Para enviar o pedido de certificado pode por exemplo ser
// codificado na codificação DER e enviado para o
// Stream out
//
}
catch(IOException e) {
}
20
5.1.4 Iniciar pedido de actualização de chaves
Para que uma chave seja substituída no final do seu ciclo de vida (é politica que determina a
duração da chave), o software cliente ou o subscritor terá de pedir um novo certificado. Para isso
terá de gerar uma nova chave pública e uma nova chave privada.
Os pedidos de actualização de chaves confiam na integridade dos certificados anteriores, por
isso não podem servir para substituição de chaves perdidas ou roubadas. Caso uma chave seja
perdida o subscritor não pode provar a sua possessão. No caso de ser roubada não é possível
destinguir o subscritor real do impostor. Em qualquer um destes casos o subscritor necessita de
fazer um novo pedido de certificado.
Determinar o final do ciclo de vida de uma chave
A classe X509Certificate do javax.security.cert (JDK) tem um método que permite verificar a
validade do certificado (checkValidity). Desta forma pode-se determinar se uma chave atingiu ou está
próxima em atingir o final do seu ciclo de vida.
Gerar pedido de actualização de chaves
Como os pedidos de actualização de chaves confiam no certificado anteriormente emitido, o
pedido de actualização de chaves terá de ser enviado de forma que seja provado que o subscritor
possui o certificado antigo. Deverá ser enviada a nova chave pública e a identificação do subscritor.
Para isso é necessário gerar um novo par de chaves (ver 5.1.2).
Uma solução simples será gerar um novo pedido de certificado (PKCS#10) e assina-lo com a
chave privada antiga. Desta forma o subscritor poderá provar a posse do certificado anterior.
Obter um objecto para assinatura
Para se obter um objecto para assinaturas, tem de ser invocado o método getInstance da classe
Signature. Este método recebe dois argumentos: o nome do algoritmo e o security provider ou
fornecedor de segurança. Para obter o algoritmo do certificado que está a expirar pode usar-se o
método getSigAlgName da classe X509Certificate. O certificado pode ser lido da seguinte forma :
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream fis = new FileInputStream("NomeDoFicheiro");
X509Certificate certx509 = (X509Certificate) cf.generateCertificate(fis);
O algoritmo de assinatura pode ser obtido com:
Signature sig = Signature.getInstance(certx509.getSigAlgName(), "SUN");
21
Iniciar o objecto de assinatura
Para que o objecto de assinatura seja iniciado é necessário passar-lhe a chave privada. A chave
privada, caso esteja implementado o protocolo PKCS#8, pode ser obtida através de um método que
a decifre e outro que a devolva. Por exemplo o JCSI implementa uma classe
PKCS8EncryptedPrivateKey que disponibiliza construtores para, por exemplo obter a chave a partir de
um Stream (ficheiro, socket, etc...), e métodos para decifrar a chave privada, por exemplo através de
uma palavra chave ( decrypt(char[] password) ), e também um método para obter a chave ( PrivateKey
getPrivateKey() ).
Assim, após obtida a chave sob a forma de um objecto PrivateKey, podemos finalmente iniciar
o objecto de assinatura.
sig.initSign(priv);
Podemos por exemplo obter o novo pedido de certificado sob a codificação DER através do
método getEncoded() da classe PKCS10CertificationRequest e assina-lo com a chave privada.
byte[] buffer = novoPedidoDeCert.getEncoded();
sig.update(buffer);
byte[] pedidoCertAssinado = sig.sign();
Envio do pedido de actualização de chaves
O pedido de actualização pode ser enviado via canal seguro usando SSL (ver 5.1.3)
5.1.5 Instalar chave privada
O software cliente tem de possibilitar o armazenamento da chave privada depois de gerada.
Pode ser guardada em diferentes suportes, cifrada e protegida por password.
Existem vários protocolos para as chaves privadas, por exemplo o PKCS#5 que especifica as
normas de cifragem com base em palavra chave, o PKCS#8 que especifica uma norma para o
sintaxe da informação, ou o PKCS#11 que um interface para tokens criptográficos para serem
usados por smartcards.
Como já vimos anteriormente, o JCSI implementa a norma PKCS#8. Podemos através desta
implementação facilmente guardar a chave privada cifrada e protegida por palavra chave da seguinte
maneira:
Guardar a chave privada
Vejamos um exemplo para guardar a chave privada através da palavra chave “myPassword”
num ficheiro:
PKCS8EncryptedPrivateKey encKey = new
PKCS8EncryptedPrivateKey(privateKey);
FileOutputStream fos = new FileOutputStream(fileName);
encKey.encrypt("myPassword".toCharArray());
fos.write(encKey.getEncoded());
22
Ler a chave privada
Vejamos agora um exemplo para ler e decifrar a chave privada guardada num ficheiro:
FileInputStream fis = new FileInputStream("NomeDoFicheiro");
PKCS8EncryptedPrivateKey encKey = new
PKCS8EncryptedPrivateKey(fis);
encKey.decrypt("myPassword".toCharArray());
PrivateKey privateKey = encKey.getPrivateKey();
5.1.6 Prova de posse de chave privada
O software cliente tem de responder a pedidos de outros componentes da PKI para provar a
posse de chave privada. Normalmente, o que se faz é cifrar alguns dados com a chave privada e
enviar como resposta para que seja decifrado com a chave pública correspondente.
Isto pode ser feito simplesmente assinando o pedido de prova de posse de chave privada com
a chave privada do subscritor e envia-lo como resposta.
Para as comunicações pode usar-se por exemplo SSL (JESSE com em 5.1.3). Para obter a
chave privada pode usar-se uma implementação do PKCS#8 ou a classe PKCS8EncryptedPrivateKey
do JCSI (ver 5.1.5), para assinar a resposta pode utilizar-se a classe Signature do JDK. (como em
5.1.4).
5.1.7 Instalar e guardar certificados
O software cliente tem de poder guardar o certificado do subscritor. Em alguns casos, quando
o formato de armazenamento é proprietário do software cliente, deve existir a possibilidade de
exportar sob o formato PKCS#12.
Não é necessário guardar de forma cifrada nem segura, porque os certificados são
23
5.1.8 Assinar e decifrar com a chave privada
O software cliente tem de ter a possibilidade de cifrar e decifrar informação com a chave
privada. Os métodos de cifragem podem variar com o tipo de aplicações. Normalmente, no envio
de mensagens, a chave privada é usada para cifrar a message digest que funciona como assinatura
digital, para que o conteúdo e a fonte da informação possa ser verificada pelos receptores. Na
recepção de mensagens, a chave privada é usada para decifrar a informação que foi cifrada pelo
emissor através da chave publica do subscritor.
Para se poder usar a chave privada é necessário que o subscritor decifre a chave através da sua
palavra chave. Caso a chave privada esteja guardada num token físico (por exemplo: smartcard) o
subscritor tem de possuir esse token.
Já vimos anteriormente como se pode obter e assinar com a chave privada (ver 5.1.4).
5.1.9 Apresentar o certificado aos outros
O software cliente tem de poder enviar o certificado do subscritor às aplicações, servidores, e
outros subscritores que necessitam saber a identidade do subscritor e a sua chave pública. A
apresentação do certificado é semelhante a uma afirmação de identidade. É necessária uma prova de
posse (ver 5.1.6) para garantir que o certificado apresentado é autentico.
A apresentação de certificados pode não ser necessária quando existe um repositório de
certificados, isto é, o certificado do subscritor pode ser pesquisado em vez de ser apresentado
directamente.
A forma de implementar esta funcionalidade é bastante semelhante à prova de posse de chave
privada. Basta que o certificado seja enviado à aplicação, servidor, utilizador, etc assinado com a
chave privada do subscritor. Desta forma pode ser apresentado o certificado e provada a posse da
chave privada.
As mensagens podem ser trocadas por exemplo através de SSL ( JESSE como anteriormente
foi discutido em 5.1.3). A obtenção da chave privada pode ser obtida através de uma implementação
do protocolo PKCS#8 (por exemplo a classe PKCS8EncryptedPrivateKey do JCSI como em 5.1.5). O
certificado pode ser lido como em 5.1.4 e assinado da seguinte forma:
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream fis = new FileInputStream("NomeDoFicheiro");
X509Certificate certx509 = (X509Certificate) cf.generateCertificate(fis);
Byte[] buffer = certx509.getEncoded();
Signature sig = Signature.getInstance(certx509.getSigAlgName(), "SUN");
sig.initSign(chavePrivada);
sig.update(buffer);
byte[] certx509Assinado = sig.sign();
Finalmente pode ser enviado à aplicação, servidor ou utilizador. (como em 5.1.3)
24
5.1.10 Iniciar pedido de revogação
O subscritor tem de ter a possibilidade de efectuar um pedido para que o seu certificado seja
anulado. Obviamente esse pedido tem de ser assinado pela chave privada do subscritor, a não ser
que a o motivo do pedido de revogação do certificado seja a perda total da chave. Neste caso a RA
ou a CA têm de iniciar o processo de revogação.
Uma forma simples de codificar esta funcionalidade em Java é codificar uma mensagem
relativa ao pedido de revogação assinada com a chave privada do subscritor (ver 5.1.4 ou 5.1.9).
Caso o subscritor tenha perdido a sua chave, deverá contactar a CA ou RA para que o seu
certificado seja revogado.
5.1.11 Iniciar pedido extensão do prazo de validade
O subscritor tem de ter a possibilidade de efectuar um pedido, para que um certificado que
esteja em vias de expirar, tenha o prazo prolongado. Se este processo é feito de forma automática ou
não depende da política de implementação.
Isto pode ser implementado em Java enviando uma mensagem assinada com a chave privada
do subscritor a pedir o prolongamento do prazo de validade do certificado (na alínea anterior). O
certificado terá de ser reemitido pela CA, caso o pedido seja atendido. Normalmente o envio de
certificados é feito segundo a norma PKCS#7. O código que se segue serve para obter os
certificados a partir de um stream (que pode ser um ficheiro ou um socket SSL).
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(
inputStream);
Depois de receber o certificado com o no prazo de validade estabelecido basta substituir o
certificado antigo pelo novo certificado.
5.2 Autoridade de Registo
A Autoridade de Registo (RA) é o componente responsável por assegurar que a ligação entre
os pares de chaves e as identidades é realizada segundo determinadas políticas. Normalmente este
componente consiste numa aplicação que um operador humano manipula para verificar as
identidades dos subscritores, no entanto algumas funções podem ser automatizadas. Nem sempre
este componente se encontra distinguido, por vezes é incluído na Autoridade de Certificação.
25
5.2.1 Verificar a identidade do subscritor
Esta função pode ou não ser automática dependendo da política de implementação. Tendo
em conta que o certificado serve para associar uma identidade a um par de chaves, a RA tem de
efectuar os testes de identidade necessários para que esta associação seja credível tendo em conta os
objectivos do uso do certificado.
Em termo práticos podem ser usadas muitas estratégias de verificação de identidade. Por
exemplo a validação automática de endereços de e-mail, ou requerer informação exaustiva acerca do
subscritor, como por exemplo (certidão de nascimento, passaporte, BI, etc....). Para aplicações em
intranets, os testes de verificação de identidade podem ser semelhantes à emissão do cartão do
funcionário da organização.
5.2.2 Aprovar ou modificar o conteúdo do certificado
O pedido de certificado é analisado, por um humano ou pelo software da RA. É verificado o
conteúdo de cada campo. Alguns campos poderão ser modificados para respeitar determinadas
políticas pré-definidas. A RA poderá aprovar ou reprovar os pedidos de certificados em função de
critérios pré-estabelecidos.
Em algumas implementações, o subscritor pode pedir certos campos como por exemplo o
nome comum. No entanto, a RA deve poder sobrepor esses pedidos para que seja cumprida uma
determinada política local de funcionamento. Esta política estabelece quais os campos serão
preenchidos pelo subscritor e quais os que serão preenchidos pela RA e ainda que campos serão
definidos pela política de funcionamento.
Em Java já vimos anteriormente como podem ser manipulados os pedidos de certificados
utilizando uma implementação do protocolo PKCS#10 (por exemplo a classe
PKCS10CertificationRequest do JCSI em 5.1.3)
O campo attributes do PKCS#10
Este campo pode ser usado para adicionar ao pedido, informação acerca do certificado ou do
subscritor. Os campos estão descritos no PKCS#6. O campo attributes está na notação ASN.1 logo é
necessário implementar classes da Java que implementem esta notação para criar estes campos
adicionais.
5.2.3 Gerar pares de chaves
Esta função é opcional, isto é, a RA pode opcionalmente gerar o par de chaves para o
subscritor, o que implica ter implementado o mesmo tipo de aplicações descritas em 5.1.2.
Este tipo de função é usada em RAs quando existe a necessidade que as chaves tenham de ser
geradas por software ou hardware dedicado existente na RA.
26
Aparentemente a geração do par de chaves pela RA, é mais insegura do que a geração local,
no entanto o software usado para gerar as chaves que existe no subscritor pode ser mais vulnerável a
diversos tipos de ataques durante o processo de geração das chaves, tendo em conta que os PC são
geralmente inseguros. As RAs podem empregar mecanismos muito seguros de hardware para gerar
os pares de chaves. As chaves são depois enviadas de forma segura ao subscritor. Esta técnica tem
no entanto a desvantagem de reduzir a credibilidade da assinatura digital. O subscritor pode afirmar
que a RA autorizou a outra pessoa o acesso à sua chave privada. A adesão ou não adesão a este
sistema é uma questão de política de implementação da RA.
5.2.4 Guardar pares de chaves
Esta função não é obrigatória e implica que a RA tenha gerado o par de chaves do subscritor
ou conheça a sua chave secreta. Se estiver implementado um serviço de recuperação de chaves, a
RA tem de manter armazenados os pares de chaves dos subscritores. A forma como as chaves são
armazenadas tem de ser o mais segura possível para não comprometer todo o sistema.
O mais comum é manter um arquivo das chaves de cifragem em vez de chaves de assinatura,
o que implica a existência de dois pares de chaves. No caso das chaves de cifragem, a perda da chave
privada implica que a informação se torne ilegível para o subscritor. Neste caso a chave pode ser
recuperada e a informação pode tornar-se novamente legível. No caso das chaves de assinatura, é
vital que apenas o subscritor tenha controlo sobre a chave, porque o que está em causa é a sua
credibilidade.
No desenvolvimento deste componente, caso seja usado o Java, têm de ser consideradas
todas a precauções de segurança para que a base de dados onde estão guardados os pares de chaves
dos subscritores, seja inviolável. O acesso à base de dados pode ser feito por JDBC. É conveniente
que o SGBD seja o mais seguro possível.
5.2.5 Distribuição de tokens
No caso das chaves serem geradas pela RA, a chave privada poderá ser entregue ao subscritor
num suporte físico (smartcard, disquete, etc...). Para que isto seja possível a chave privada terá de ser
instalada num token. A norma que é utilizada para interface com funções de PKI existentes num
smartcard é o PKCS#11.
5.2.6 Testes de posse de chave privada
Antes da RA aprovar um certificado que associe uma chave pública a uma identidade, é
necessário saber se o subscritor possui a chave privada correspondente. Para isso a RA pode por
exemplo enviar uma determinada informação aleatória ao subscritor e pedir que a assine com a sua
chave privada e a envie de novo à RA. Se a RA confirmar a assinatura da mensagem, quer dizer que
o subscritor é realmente detentor da chave privada.
Para implementar em Java esta função basta obter a chave publica do subscritor. Para isso
pode usar-se ou programar uma implementação da norma PKCS#10 (por exemplo a classe
PKCS10CertificationRequest do JCSI em 5.1.3). Depois do pedido de certificado ter ser recebido pela
27
RA pode-se obter a chave pública do subscritor invocando o método getPublicKey(). Para verificar se a
assinatura é autentica pode fazer-se:
Obter chave pública
PublicKey chavePublica= pedidoDeCertificado.getPublicKey();
Iniciar objecto de assinatura
Inicia-se uma instância do objecto de assinatura para verificação com o algoritmo prédefinido para o certificado do subscritor.
Signature assinatura = Signature.getInstance(algoritmo);
assinatura.initVerify(chavePublica);
Assinar a mensagem
Obtém-se a mensagem sob a forma de array de bytes e passa-se a mensagem ao objecto de
assinatura.
byte[] mensagem = "Mensagem".getBytes();
assinatura.update(mensagem);
Verificar a assinatura
Compara-se a assinatura obtida com a assinatura que a mensagem transporta.
if (assinatura.verify(assinatura_da_mensagem))
{
// assinatura válida
}
else
{
// assinatura inválida
}
5.2.7 Atribuição de DN e modificação do conteúdo do certificado
A RA deve poder editar o Distinghished Name (DN) dos certificados e outro tipo de
conteúdos para corresponder a determinadas políticas. Se existir uma verificação automática de
verificações de pedidos, é comum por exemplo que haja um formato normalizado para o DN, ou
numeração sequencial para os certificados.
28
5.3 Autoridade de Certificação
A Autoridade de Certificação (CA) é o componente da PKI responsável pela gestão dos
certificados. Inicialmente a CA cria os certificados e adiciona-lhes a “assinatura CA” que garante a
integridade do certificado. Não pode ser modificado sem invalidar a assinatura, por isso, qualquer
certificado com uma “assinatura CA” válida é garantido ter os mesmos conteúdos desde a sua
geração. A CA é também responsável por revogar (anular) os certificados que por qualquer motivo
deixam de ser válidos.
As políticas de funcionamento da CA pode necessitar de administração humana para aprovar
a criação, a revogação de certificados. O funcionamento da CA pode também ser automatizado. A
função que normalmente é executada por um operador humano é a de verificação da identidade do
subscritor. Como já foi visto anteriormente, esta função pode ser, caso exista, incorporada numa
RA, e a CA só deve emitir os certificados se forem anteriormente aprovados pela RA sem a
necessidade intervenção humana.
5.3.1 Responder a pedidos de renovação de certificados
A CA pode, de acordo com uma determinada política, aprovar pedidos dos subscritores para
renovação de certificados (5.1.4 e 5.1.11), quer relativamente ao prazo de validade das chaves, quer a
renovação das chaves.
Partindo do principio que a identidade do subscritor foi provada quando o certificado original
foi emitido, estas funções não exigem o envolvimento da RA. De qualquer forma, se houver
políticas que o exijam, pode ser revalidada a identidade do subscritor..
A implementação desta função em Java deve receber o pedido de renovação, desempacotar o
pedido e estabelecer o novo período de validade e reenviar o certificado ao subscritor, isto se o
pedido for de prolongamento da validade do certificado. Caso o pedido seja de renovação das
chaves terá de ser exigida uma prova de posse da chave privada para garantir que a chave pública
corresponde à chave privada do subscritor.
5.3.2 Modificar ou aprovar modificações do conteúdo do certificado
De forma similar RA, também a CA pode implementar a funcionalidade de responder a
pedidos de modificação do conteúdo ou modificar ela mesma o conteúdo de um certificado. Esta
função pode ser desempenhada por um operador humano. As modificações podem incluir
extensões de certificados, por exemplo, extensões Netscape ou Microsoft.
A implementação em Java desta funcionalidade deve seguir os seguintes passos: Caso seja um
pedido de um subscritor, esse pedido deve ser desempacotado, a CA deve depois aceitar ou reprovar
o pedido, caso o pedido seja aprovado o certificado deve ser alterado e reenviado ao subscritor.
Caso seja uma alteração do conteúdo pela CA, o certificado deve ser alterado e reenviado ao
subscritor.
29
5.3.3 Iniciar e aprovar revogação
A CA terá de aprovar pedidos de revogação de certificados provenientes da RA ou do
subscritor. A CA também poderá iniciar o processo de revogação de certificados de acordo com
uma determinada política (por exemplo: prazo de validade das chaves). No caso de serem envidados
pedidos de revogação pela RA e pelo subscritor é porque as chaves foram perdidas ou de alguma
forma encontram-se comprometidas no que diz respeito a segurança.
5.3.4 Criar certificado raiz auto assinado
A CA deve poder criar e assinar certificados CA para ela própria e para as CAs subordinadas.
Opcionalmente, o certificado CA poderá ser gerado por uma outra entidade que mantenha uma
relação de confiança.
O certificado de nível de topo ou certificado raiz é sempre auto assinado. O simples facto do
certificado conter uma chave pública não se lhe deve atribuir confiança, porque qualquer um pode
criar um certificado auto assinado com o distinguished name de uma CA bem conhecida. A confiança
deve advir do facto de a chave pública desse certificado ser uma chave pública bem conhecida para
essa CA que pode ser verificada a partir de outras fontes como por exemplo anúncios. A única razão
pela chave pública ser guardada no certificado raiz é porque é exigido o seu preenchimento no
formato de certificados na maior parte das ferramentas. Neste caso, o certificado é usado para que
transporte a chave pública da CA para que possa ser verificada através de outras fontes.
Gerar um certificado a partir de um par de chaves
O comando genkey do utilitário keytool pode ser usado para criar um par de chaves e para
empacotar a chave pública num certificado auto assinado. Neste caso, é necessário atribuir uma
palavra chave para o armazém de chaves que irá conter a chave secreta e essa palavra chave.
Também será necessário providenciar informação relativa à entidade que irá possuir o certificado.
Também é possível criar um novo certificado usando um par de chaves associado a um
certificado gerado anteriormente.
Gerar um certificado CA auto assinado com o JCSI
Para gerar um certificado CA auto assinado pode usar-se o seguinte construtor da classe
X509CertGen :
X509CertGen(String issName, Signature sig)
5.3.5 Emissão de certificados
A CA tem de poder emitir e assinar certificados. A assinatura garante aos receptores que o
certificado foi emitido de acordo com a política de publicação da CA. A chave privada para efectuar
esta assinatura deve estar bem segura.
O JDK não disponibiliza ferramentas de programação para a criação de certificados, apenas
disponibiliza a capacidade de importar certificados e usa-los de várias formas. Por exemplo o JCSI
30
disponibiliza classes para manipulação e geração de certificados. Outra alternativa é programar as
classes para geração e manipulação de certificados a partir das normas X500 e X509.
Os certificados X509 são constituidos pela seguinte informação:
Versão
Número de Série
Identificador de algoritmo para assinatura
X500 (nome da entidade geradora, conhecido como distinguished name)
Período de validade
Nome da entidade identificada com a chave pública (subject name)
Informação relativa à chave publica dessa entidade (chave pública, algoritmo,
parâmetros)
Os X500 Distinguished Names são constituídos por :
Nome comum
Nome do departamento
Nome da organização
Nome da localidade
Nome do estado ou província
Código do país
Vejamos como poderia ser criado um certificado para um determinado subscritor:
X509CertGen cg = new X509CertGen(caSignature, caCert);
cg.setPublicKey(userPublicKey);
cg.setSerialNumber(BigInteger.valueOf((long)12345678 ));
cg.setSubjectDN("CN = John Smith, OU=Security, O=DSTC, C=AU");
cg.setValidity(365);
cg.setSubjectEmail("[email protected]");
X509Certificate userCert = cg.getCertificate();
5.3.6 Disponibilizar os certificados aos subscritores
A CA deve ter a capacidade de entregar os certificados aos subscritores. Isto pode não ser
obrigatório, isto é, caso exista um Repositório de Certificados, a solução de PKI pode requerer ao
subscritor que obtenha o seu certificado a directamente a partir desse repositório após ter sido
publicado. No entanto, a maior parte das soluções implementam a capacidade de enviar o
certificado ao subscritor. Normalmente a CA indica ao subscritor onde pode descarregar o
certificado.
31
O formato usado para a entrega de certificados é o PKCS#7. O JDK não disponibiliza
ferramentas para criar ou manipular este formato. Existem duas alternativas, ou se desenvolvem
classes para implementar este protocolo, ou utiliza-se um framework que o implemente. Por exemplo
o IAIK, implementa uma classe chamada PKCS7CertList que manipula correntes de certificados
compatíveis com o Netscape Navigator e Microsoft Explorer. Esta classe disponibiliza vários métodos e
construtores para criar um objecto assinado que contém uma lista de certificados. Essa lista pode ser
escrita ou lida de um ficheiro (com a extenção .p7c). Vejamos um exemplo para escrever a lista:
X509Certificate[] certs = ...;
PKCS7CertList pkcs7 = new PKCS7CertList();
pkcs7.setCertificateList(certs);
pkcs7.writeTo(new FileOutputStream(pkcs7File));
Para ler a lista:
PKCS7CertList pkcs7 = new PKCS7CertList(new FileInputStream("certs.p7c"));
X509Certificate[] certs = pkcs7.getCertificateList();
5.3.7 Publicação dos certificados
A CA deve possuir a capacidade de enviar os certificados ao Repositório de Certificados,
onde serão disponibilizados a quem necessitar um cópia.
Relativamente à implementação desta funcionalidade em Java, o que pode ser feito é, por
exemplo, uma aplicação cliente servidor, em que o cliente (implementado na CA) envie o certificado,
depois da sua emissão, ao servidor (Repositório de certificados) para que seja publicado.
5.3.8 Revogar certificados (Adicionar à CRL)
A CA deve poder revogar certificados. Para isso será necessário adicionar o certificado à Lista
de Certificados Revogados (CRL) e tornar o estado do certificado para certificado revogado no
repositório.
No JDK não existem classes para criar, ou manipular CRLs. As classe que existem apenas
permitem obter informação (ler) o conteúdo das CRLs. Mais uma vez, existem duas alternativas, ou
criamos classes que permitam manipular CRLs a partir da notação ASN.1, ou então usamos um
framework que já as implemente. Por exemplo no JCSI, existe uma classe chamada X509CRLGen que
permite criar uma CRL. Vejamos como é que isso pode ser feito:
X509CRLGen crlGen = new X509CRLGen(caSignature, caCert);
cg.setThisUpdate(new Date());
Calendar c = Calendar.getInstance();
c.set(2002,5,21);
cg.setNextUpdate(c.getTime());
cg.setCRLNumber(BigInteger.valueOf((long)635));
Agora vejamos como podem ser adicionados certificados à lista. Para isso basta invocar o
método addRevokedCert com o número de série do certificado revogado:
cg.addRevokedCert(BigInteger.valueOf((long)35467));
cg.addRevokedCert(BigInteger.valueOf((long)4587467));
32
Para obtermos um objecto com a lista basta fazer:
X509CRL crl = crlGen.getCRL();
5.3.9 Publicar CRL
A CA deve enviar a CRL para o Repositório de certificados para que seja disponibilizada a
quem necessitar uma cópia. A CA assina a CRL para que os receptores saibam que se trata de uma
CRL válida. Dependendo de uma determinada política, as CRLs podem ser enviadas periodicamente
ou quando acontece uma revogação.
Se optar-mos pelo envio das CRLs cada vez que um certificado seja revogado o
procedimento poderá ser semelhante à publicação de certificados, isto é, basta construir uma
aplicação do tipo cliente servidor, em que o servidor corre no Repositório de certificados e o cliente
na CA. Depois de um certificado ser revogado, a CRL é enviada ao servidor para que seja publicada.
5.3.10 Pedido de Certificação Cruzada
A CA deve poder enviar pedidos a outras CAs pedindo os seus certificados, para que por
exemplo, pedidos assinados pela CA possam ser aceites por outra CA remota. Ainda não existem
normas para este tipo de funcionalidades. As implementações limitam-se a fazer certificação cruzada
dentro de uma solução PKI..
Como ainda não existem normas também não existem implementações desta funcionalidade
em frameworks de Java.
5.3.11 Aceitar Certificação Cruzada
A CA deve poder responder a pedidos de certificação cruzada, isto é, deve responder a
pedidos de certificação de outras CAs indicando que irão aceitar os seus certificados.
Da mesma forma que os pedidos de certificação cruzada não existem ainda normas para esta
funcionalidade, consequentemente a forma de implementação é distinta para cada solução.
33
5.4 Repositório de Certificados
O Repositório de Certificados consiste num serviço de directório que permite que os
certificados e as CRLs sejam devolvidas em função de pedidos. Este componente é por vezes
implementado como parte de um serviço de directório de propósito geral como por exemplo o
LDAP. No entanto pode também ser um serviço especifico da solução PKI e estar até inserido no
componente de Autoridade de Certificação.
Para aceder a um serviço de directório LDAP, existe uma API incluída no JDK 1.3 que se
chama JNDI. O JNDI não só permite o acesso a serviços de directório LDAP como também a
outros tipos de serviços e protocolos como por exemplo o DNS, NDS, NIS e X500.
Para implementar um serviço de directório LDAP pode usar-se o OpenLDAP ou se se optar
por uma implementação em Java existe o JavaLDAP. Ambos são de domínio público. O servidor
JavaLDAP funciona como motor do protocolo LDAP e disponibiliza acesso a informação de várias
fontes a um qualquer cliente LDAP.
5.4.1 Armazenar certificados e CRLs
O repositório de Certificados tem de possibilitar que os certificados e as CRLs possam ser
armazenados. Se usar-mos um serviço de directório terá de se usar uma API para publicar os
certificados, caso seja usada uma base de dados poderemos criar uma aplicação que através de JDBC
permita o acesso a essa base de dados para guardar os certificados as CRLs e outra informação que
possa ser útil.
5.4.2 Disponibilizar Certificados e CRLs
O repositório de Certificados tem de receber pedidos para pesquisar um determinado
certificado ou CRL e disponibilizar uma cópia. Como já foi dito, podem adoptar-se duas
abordagens. Ou se utiliza, e é recomendado que assim seja, um serviço de directório, ou o JDBC
para aceder a uma Base de Dados onde se encontram guardados os Certificados e as CRLs. Depois
de encontrado o registo relativo ao pedido, deve ser disponibilizada um cópia.
5.4.3 Verificar o estado do Certificado
O repositório de Certificados tem de disponibilizar a capacidade de verificar o estado de um
certificado. Isto pode ser feito como parte da funcionalidade de disponibilizar o certificado, isto é, o
estado está contido no certificado quando este é disponibilizado, ou então pode ser uma função
separada em que apenas retorna uma flag indicadora do estado em vez de todo o certificado.
34
Algumas norma estão a ser desenvolvidas para esta funcionalidade. O Online Certificate Status
Protocol (OCSP) é uma dessas norma. A existência de uma norma que permita verificar o estado de
um certificado sem que seja necessário obter o certificado completo, tem grandes vantagens,
nomeadamente a redução da largura de banda requerida.
5.5 Aplicações ou Utilizadores
As aplicações e os utilizadores que usam certificados para interagir com os subscritores que os
possuem, utilizam esses certificados para obter serviços de segurança de acordo com o propósito
desses certificados. Fala-se em aplicações ou utilizadores porque ambos podem obter esses serviços
de segurança. Um exemplo de uma aplicação é um servidor Web e um exemplo de um utilizador
humano pode ser utilizador de correio electrónico de forma segura. Estas entidades são
normalmente designadas por “entidades que confiam” (relying entities) pois confiam na representação
da identidade do subscritor por parte dos certificados.
5.5.1 Receber certificados
A aplicação deve receber certificados de subscritores. O subscritor pode apresentar o
certificado para autenticar a sua identidade ou para que a informação lhe seja enviada de forma
segura (cifrada).
Esta funcionalidade não é tecnicamente necessária. A aplicação poderá alternativamente obter
o certificado do subscritor a partir do Repositório de Certificados. No entanto existem protocolos
(SSL, S/MIME) que permitem uma troca directa de certificados entre o subscritor e a aplicação
(5.1.3).
Caso o certificado seja usado para autenticação, deve ser acompanhado com um teste de
posse do certificado que confirma que o subscritor realmente possui o certificado. A forma de
implementação é semelhante a 5.2.6.
5.5.2 Pedir Certificados
A aplicação deve poder elaborar pedidos de certificados ao Repositório de Certificados. Esta
função é necessária para que a aplicação possa cifrar as mensagens com a chave pública do
subscritor para que depois as mensagens lhe sejam envidadas de forma segura. Esta função pode ser
considerada um cliente da função descrita em 5.4.2.
5.5.3 Validar Certificado
A aplicação deve poder validar certificados. Para isso existem duas alternativas: Os se consulta
a lista de certificados revogados contactando o Repositório de Certificados, podendo concluir se
esse certificado continua válido; ou alternativamente usando um protocolo como por exemplo o
35
OCSP, que interroga o Repositório de Certificados ou a CA sobre a validade de um determinado
certificado. Esta função está interligada com a função descrita em 5.4.3.
5.5.4 Verificar identidades e Assinaturas
Dependendo nos propósitos dos certificados e das necessidades da aplicação, esta pode ter a
capacidade de usar o certificado para identificar a identidade do subscritor. A identidade do
subscritor pode ser verificada através da sua assinatura.
Para se implementar esta funcionalidade usando Java podem seguir-se os seguintes passos:
Obter a chave pública do subscritor e criar um objecto de assinatura;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream fis = new FileInputStream("NomeDoFicheiro");
X509Certificate certx509 = (X509Certificate) cf.generateCertificate(fis);
PublicKey certx509.getPublicKey();
Assinar a mensagem e finalmente verificar a assinatura (como em 5.2.6).
5.5.5 Cifrar com o Certificado
Dependendo nos propósitos dos certificados e das necessidades da aplicação, esta pode ter a
capacidade de usar o certificado para cifrar informação que apenas o subscritor possa ler. Para isso a
informação de ser cifrada com a chave publica do subscritor.
Em algumas implementações, utiliza-se criptografia de chave secreta em conjunto com chave
pública. É feito da seguinte forma: A chave pública do subscritor é usada para cifrar uma chave de
sessão que consiste numa chave secreta que é gerada pela aplicação. O corpo da mensagem é então
cifrado com essa chave. O subscritor deve usar a sua chave secreta para decifrar a chave de sessão de
finalmente usar essa chave para decifrar o resto da mensagem. Este método é usado
fundamentalmente por causa do desempenho, isto é, os algoritmos de chave secreta são bastante
mais rápidos que os de chave publica. Este método é designado de envelope digital e é usado pelo
PKCS#7.
O JCSI contém um package (com.dstc.security.cms )que manipula este protocolo. Se for desejado
implementar este protocolo em java é necessário construir classes baseadas na notação ASN.1 tal
como está na especificação PKCS#7. Para implementar esta função usando o JCSI basta usar a
classe CMSCipher. Esta classe disponibiliza um método de iniciação initEncrypt, que recebe um vector
com os certificados dos receptores da mensagem e o algoritmo de cifragem de chave secreta
(DESede, RC2, RC2/40). Depois de criado e iniciado o objecto de cifragem as mensagens podem ser
passadas ao objecto invocando o método setDataToBeEncrypted que recebe a mensagem sob a forma
de um array de bytes. Finalmente para cifrar a mensagem e envia-la a um stream usa-se o método
encrypt que envia a mensagem cifrada sob a forma ASN.1 BER..
36
6. Conclusão
Para implementar uma PKI em Java, existe um número considerável de ferramentas ou APIs
disponíveis. Algumas são de domínio público, outras possuem licenças gratuitas para fins educativos, e outras
possuem licenças puramente comerciais, embora disponibilizem licenças para avaliação. Normalmente as APIs de
domínio público apenas implementam um security provider compatível com o JCE da Sun. Se for desejado
implementar uma PKI usando apenas ferramentas de domínio público, terão de ser implementadas “de raiz”
algumas funcionalidades, nomeadamente as especificações PKCS e a notação ASN.1. Algumas ferramentas que
disponibilizam licenças para fins educacionais, por exemplo o JCSI, já possuem funcionalidades que ultrapassam
a mera implementação de algoritmos criptográficos, disponibilizando packages com classes que permitem a
implementação das principais funcionalidades de uma PKI.. No caso do JCSI, existe a possibilidade de ser usado
para fins comerciais, contactando a DSTC. As ferramentas puramente comerciais são obviamente as mais
completas, no entanto, por serem puramente comerciais, decidi não inclui-las neste trabalho. Normalmente estas
ferramentas são desenvolvidas pelas principais Autoridades de Certificação existentes.
Para além do Java existem outras opções de implementação para os componentes da PKI. É comum
existirem implementações de algumas funções da RA ou da CA em servidores Web através de módulos de SSL,
CGIs, Servlets, Perl, etc... Para a comunicação segura através de sockets, existe o OpenSSL que é de domínio
público. Nas aplicações, as linguagens de programação usadas na implementação são sempre bastante diversas. O
que tem realmente de ser respeitado, são as especificações existentes para as trocas de certificados com o
Repositório de Certificados ou com a CA.
Considero que utilizar a linguagem Java para o desenvolvimento de uma PKI é uma boa opção,
porque: em primeiro lugar se beneficia das vantagens do Java, nomeadamente a independência relativamente à
plataforma (*NIX, Microsoft, Mac, etc...) ; em segundo lugar, o facto de já existirem com vimos anteriormente
soluções para cada um dos componentes da PKI, inclusivamente para as comunicações seguras ou mesmo para
serviços de directório (LDAP).
Para terminar, creio que este trabalho pode ser uma ferramenta interessante para apoiar o
desenvolvimento de PKIs, fundamentalmente como orientação na identificação dos componentes e das
funcionalidades obrigatórias e opcionais da PKI, assim como na orientação no desenvolvimento dessas
funcionalidades através dos exemplos ou das referências às classes e métodos de APIs que as implemente.
Janeiro de 2001, Pedro Miguel Félix Alípio
37
7. Referências
Implementação de um CA de domínio público
http://www.OpenCA.org/
APIs Criptográficos
http://java.sun.com/security/JCE1.2/earlyaccess/apidoc/
http://java.sun.com/products/jdk/1.2/docs/api/ (JCA)
http://www.dstc.edu.au (JCSI)
http://www.bouncycastle.org/
http://www.virtualunlimited.com/products/beecrypt/
http://xsi.unil.ch/java/IAIK/Readme.html
http://www.eracom.com.au/
http://www.protekt.com/
http://www.freestylesoft.com/products/crypto/avalanche.html
38
PKI em geral
http://www.rsa.com/rsalabs/pubs/PKCS/
http://www.netscape.com/eng/security/certs.html (Certificados Netscape)
http://www.infoseceng.com/corppki.htm
http://www1.umn.edu/oit/arch/sec-strat/essrprt.htm
http://www.entrust.org/resourcecenter/docs/protocols_pki.htm
http://conferences.oreilly.com/java/news/java_pki_0200.html
http://www.tristone.com/pki/pki2.html
http://www.baltimore.com
http://www.rsasecurity.com
http://www.certicom.com
http://www.verisign.com
http://www.phaos.com
39