Sessões laboratoriais de CA (2006/2007)


Aula 1 - Arquitectura Cliente-Servidor

Pretende-se construir uma plataforma que permita a um número arbitrário de clientes comunicar com um servidor que escuta num dado port (e.g. 4567). O servidor atribui um número de ordem a cada cliente, e simplesmente faz o dump do texto enviado por cada cliente (prefixando cada linha com o respectivo número de ordem). Quando um cliente fecha a ligação, o servidor assinala o facto (e.g. imprimindo [n], onde n é o número do cliente).

Algumas classes relevantes:

Exemplo da execução do servidor (que comunica com 3 clientes):

$ java Servidor
1 : daskj djdhs slfghfjs askj
1 : asdkdh fdhss
1 : sjd
2 : iidhs
2 : asdjhf sdga
2 : sadjjd d dhhsj
3 : djsh
1 : sh dh d   d
3 : jdhd kasjdh as
2 : dsaj dasjh
3 : asdj dhdhsjsh
[3]
2 : sjdh
1 : dhgd ss
[1]
2 : djdj
[2]


Aula 2 - Cifra de ficheiro utilizando JCA/JCE

Pretende-se cifrar o conteudo de um ficheiro. Para tal far-se-á uso da funcionalidade oferecida pela JCA/JCE, em particular a implementação de cifras simétricas.

O objectivo é então o de definir dois pequenos programas Java: Um primeiro que cifra um ficheiro (e.g. texto_limpo.txt) por intermédio de uma cifra simétrica (e.g. cifra sequêncial RC4). Um segundo que decifra o criptograma obtido para recuperar o texto limpo.

Para simplificar vamos utilizar uma chave secreta fixa, definida no código na forma de um array de bytes, e convertida numa chave secreta adequada utilizando a classe SecretKeySpec.

É também interessante verificar que o criptograma gerado é compatível com outras plataformas que implementam a mesma cifra. O comando seguinte utiliza o openssl para decifrar um ficheiro cifrado com RC4 (a chave tem de ser fornecida em hexadecimal).

openssl enc -d -rc4 -in <criptograma> -out <ficheiro resultado> -K <chave> -iv 0

Algumas classes relevantes:

Outra documentação relevante:

Aula 3 - Canal seguro entre Cliente/Servidor

Pretende-se completar/modificar o código realizado nas aulas anteriores por forma a que o Cliente comunique de forma segura (confidêncial) com o Servidor. Para tal deve-se utilizar uma cifra por blocos (e.g. AES) num modo de funcionamento apropriado.

Observações:

  • A escolha do modo deve ser adequado à natureza da conexão entre o cliente e o servidor. Em particular, deve-se tomar em atenção as questões de buffering e sincronização...
    • Se se optar por uma Stream "interactiva", pode-se optar por CipherOutputStream e CipherInputStream com uma cifra num modo "sequêncial" (obs.: experimente utilizar um modo por blocos para ter percepção sobre os problemas dessa solução...)
    • Se optar por transmissão assíncrona de objectos, por optar por utilizar SealedObject sobre uma ObjectStream. Nesse caso pode utilizar um modo por blocos (e.g. CBC).
  • Em qualquer dos casos, terá sempre de tratar da inicialização e transmissão do Initialization Vector.
  • Estando nós a utilizar uma cifra simétrica, temos de garantir que cliente/servidor acordam na chave utilizada. Para simplificar, podemos admitir que guardamos a chave num ficheiro (gerada por um pequeno programa com base na funcionalidade da classe KeyGenerator) que é disponibilizado a ambos os programas. Adiante, dicutiremos formas mais apropriadas de estabelecer o acordo de chaves entre as partes...

Algumas classes relevantes (para além das já estudadas...):


Aula 4 - Canal seguro entre Cliente/Servidor (continuação)

Pretende-se:

  • (Se for o caso...) Concluir a implementação da aula anterior;
  • Implementar estratégia alternativa (CipherStream vs. SealedObject).


Aula 5 - Acordo de chaves Diffie-Hellman

O objectivo desta aula é adicionar à aplicação Cliente/Servidor suporte para o protocolo de acordo de chaves Diffie-Hellman. Para tal deverá ser conveniente estudar/adaptar o programa de exemplo apresentado em JCE Reference Guide (Appendix F).

Novas classes:


Aula 6 - Implementação do protocolo Station to Station

Pretende-se:

  • (Se for o caso...) Concluir a implementação da aula anterior (acordo de chaves Diffie Hellman);
  • Complementar o programa de acordo de chaves para incluir a funcionalidade do protocolo Station to Station. Recorde que nesse protocolo é adicionado uma traca de assinaturas (cifrada com a chave de sessão negociada), i.e.:
    1. Alice -> Bob : g^x
    2. Alice <- Bob : g^y, EK(SB(g^y, g^x))
    3. Alice -> Bob : EK(SA(g^x, g^y))

Um requisito adicional neste protocolo é a manipulação de pares de chaves de cifras assimétricas (e.g. RSA). Para tal deve produzir um pequeno programa que gere os pares de chaves para cada um dos intervenientes e os guarde em ficheiros que serão lidos pela aplicação Cliente/Servidor.

Novas Classes:


Aula 7 - Garantias de Integridade

Tendo já abordado os aspectos de confidencialidade e autenticidade na comunicação Cliente/Servidor, falta-nos considerar a integridade da mensagem transmitida (i.e. garantir que não é possível manipular/alterar a mensagem enquanto em trânsito). Para tal devemos fazer uso de (H)MACs (classe javax.crypto.Mac).

Obs.: Uma sugestão para integrar a utilização de MACs na aplicação existente consiste em seguir a estratégia adoptada em CipherStream ou SealedObject: a de encapsular a sua funcionalidade numa classe responsável pela comunicação...


Aula 8 - Utilização de Certificados em Java

Pretende-se certificar as chaves públicas utilizadas no protocolo Station-to-Station com base em certificados X509. Para tal, disponibiliza-se:

  • Certificado de chave pública do Servidor: servidor.crt
  • Chave privada do Servidor (codificada em PKCS8): servidor.der
  • Certificado de chave pública do Cliente: cliente.crt
  • Chave privada do Cliente (codificada em PKCS8): cliente.der
  • Certificado auto-assinado da autoridade de certificação: ca.crt

Para facilitar o estudo da manipulação de certificados X509, disponibiliza-se um programa que verifica a validade de uma cadeia de certificação: ValidateCertPath.java.

Classes requeridas:

Outra documentação relevante:


Aula 9 - Geração de Certificados

Nesta sessão iremos fazer uso do openssl para construir uma pequena autoridade de certificação.

O processo de emissão de certificados X509 passa pelos seguintes passos:

  1. - O utilizador gera um par de chaves;
  2. - O utilizador produz um "pedido de certificado" que contém a sua identificação e a sua chave pública, que é assinado com a sua chave privada (o que certifica que quem solicita o certificado está na posse da respectiva chave privada);
  3. - A autoridade de certificação valida os dados contidos no certificado e, no caso de certificar positivamente esses dados, emite o certificado de chave pública correspondente.
  4. - O certificado é enviado ao utilizador e, eventualmente, publicado por outros meios (e.g. serviço de directoria).

Para cada um destes passos iremos fazer uso dos comandos respectivos do openssl.

Geração de chaves:

openssl genrsa -out grupoXPTO.key

Para utilizar a chave privada no Java é conveniente converter o seu formato para PKCS8

penssl pkcs8 -topk8 -nocrypt -in grupoXPTO.key -outform der -out grupoXptoPrivKey.der

Geração do pedido de certificado:

openssl req -new -key grupoXPTO.key -out grupoXPTO.csr 

Emissão do certificado: A emissão de certificados é normalmente realizada com o auxílio de scripts que invocam o comando openssl com os argumentos apropriados. Existem duas scripts normalmente utilizadas para este efeito:

  • CA.pl - distribuída com o "openssl".
  • sign.sh - distribuída com o "mod_ssl". Espera encontrar ficheiros ca.key e ca.crt.

Produção de PKCS12: Para certas utilizações (e.g. browsers, leitores de email, etc.) é conveniente encapsularmos o certificado e respectiva chave privada num PKCS12.

openssl pkcs12 -export -chain -CAfile cacert.pem -name GrupoXPTO -aes128 -inkey grupoXPTO.key -in grupoXPTO.crt -out GrupoXPTO.p12

Verificação dos certificados:

openssl verify -CAfile cacert.pem cert1.crt cert2.crt ...

utilizando este Certificado da autoridade de certificação de raiz.

Apontadores úteis:


r19 - 09 Dec 2007 - 02:42:54 - JoseBacelarAlmeida
This site is powered by the TWiki collaboration platform Copyright © by the contributing authors. Ideas, requests, problems? Send feedback.
Syndicate this site RSSATOM