MSDPA-0607
Java Cryptography Architecture
(JCA)
Segurança e Privacidade em
Sistemas de Armazenamento
e Transporte de Dados
Rui Manuel C. O. Afonseca
Índice
JCA
Princípios
Arquitectura
Principais Objectos
Exemplo
Problema
Resolução Conceptual (4 Camadas)
Camada Criptográfica
Detalhes de Implementação (JCA)
Protocolos de Comunicação
Certificados X.509
Conclusões
JCA - Princípios
Independente da plataforma (Java)
Fornece uma API para serviços
criptográficos
Independente da implementação
Extensível
JCA - Arquitectura
Engine Classes
Providers
Provider fornecido por omissão.
Provider IAIK
Packages que fornecem implementações de serviços
criptográficos.
Provider SUN
Define abstractamente um serviço criptográfico (sem
implementação).
Mais completa e está integrada de forma elegante com a
API para manipulação de estruturas de dados ASN.1
Java Cryptography Extension (JCE)
Extensão à JCA que inclui técnicas criptográficas mais
poderosas. (Opcional até a versão 1.4)
JCA / JCE– Principais Objectos
JCA
Signature
X509Certificate
KeyStore
JCE
Cipher
KeyGenerator
SealedObject
Exemplo
Proposto pelo Professor Manuel Bernardo Barbosa,
DI, U. Minho – Criptografia Aplicada 2003/2004
Implementação de uma aplicação de Chat
Funcionalidades protegidas por técnicas criptográficas
Identificação e anonimato dos utilizadores
Estabelecimento de canais seguros de comunicação
Com servidores
Ligações ponto a ponto (peer-to-peer)
Mensagens off-line
etc.
Exemplo – Aplicação de Chat
Sala de Conversação
Conversação Privada
Entidades do Sistema
Autoridade de Certificação Externa
Autoridade de Certificação Dedicada
Servidor de Chat
Cliente de Chat
Ligações Seguras
Cliente – Servidor
1.
•
Envelope Digital
Cliente – Cliente
2.
•
Station-to-Station
Cliente – Chat CA
3.
•
Chave Publica
Servidor – Chat CA
4.
•
Chave Publica
Desenho Conceptual
Camada de Interface
Swing
Awt
Camada operacional
Thread’s
Camada criptográfica
Security
IAIK
Camada de Rede
Socket’s
4 Camadas
Interface
Operacional
Criptográfica
Rede
Comunicações Seguras
Envelope Digital
Entidade “A” cria a chave simétrica K
“A” cifra K com a chave publica de “B”
“A” envia o criptograma para “B”
“B” decifra o criptograma com a sua chave
privada e obtém K
Comunicações Seguras (cont.)
Station To Station
DH
Melhoramento
“A” gera um número aleatório grande x
“A” calcula X = gx (mod n) e envia-o ao “B”
“B” gera um número aleatório grande y
“B” calcula Y = gy (mod n) e envia-o ao “A”
Ambos conseguem calcular K = Xy (mod n) = Yx (mod n)
Acordada a chave de sessão K, os agentes assinam
digitalmente o par ordenado (X, Y)
Estas assinaturas são trocadas entre os agentes, cifradas
com a chave acordada
Caso as assinaturas sejam recuperadas e verificadas com
sucesso o protocolo terminou com sucesso
StationToStation (Passo 1 de 3)
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH");
apg.init(512);
AlgorithmParameters ap = apg.generateParameters();
DHParameterSpec dhsp = (DHParameterSpec) ap.getParameterSpec(DHParameterSpec.class);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
BigInteger x = new BigInteger(512, random);
BigInteger gx = dhsp.getG().modPow(x, dhsp.getP());
oos.writeObject(gx);
BigInteger gy = (BigInteger) ois.readObject();
Determinar Chave K
BigInteger k = gy.modPow(x, dhsp.getP());
512 bits = 64 B => [99999999999999999999999999999999999999999999999999999999999999]
StationToStation (Passo 2 de 3)
DESKeySpec sks = new DESKeySpec(k.toByteArray());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(sks);
enc.init(Cipher.ENCRYPT_MODE, sk);
Cipher dec = Cipher.getInstance("DES/ECB/PKCS5Padding");
dec.init(Cipher.DECRYPT_MODE, sk);
Inicialização
Cipher enc = Cipher.getInstance("DES/ECB/PKCS5Padding","IAIK")
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(mypri);
sig.update(gx.toByteArray());
sig.update(gy.toByteArray());
byte[] assinaturaXY = sig.sign();
SealedObject sigXY = new SealedObject(assinaturaXY, enc);
oos.writeObject(sigXY);
Assinar
Cifrar
Enviar
StationToStation (Passo 3 de 3)
SealedObject sigXY2 = (SealedObject) ois.readObject();
Ler o criptograma
byte[] assinaturaXY2 = (byte[]) sigXY2.getObject(dec);
Decifrar – Obter a
assinatura
sig.initVerify(pub);
sig.update(gx.toByteArray());
sig.update(gy.toByteArray());
if( sig.verify(assinaturaXY2) )
{
return true;
}
else
{
return false;
}
Verificar
assinatura
Certificados X.509
Autoridades de Certificação
Emitem certificados
Revogam certificados (CRL / OCSP)
Clientes
Criam pedidos de certificado
Verificam validade de certificados
Assinam mensagens (chave privada)
Cifram mensagens (chave publica)
Criar Certificado (Passo 1 de 2)
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
kpg.initialize(1024,sr);
KeyPair clikp = kpg.generateKeyPair();
Gerar
par de
chaves
PrivateKey cliPri = clikp.getPrivate();
PublicKey cliPub = clikp.getPublic();
X509Certificate x509cert = new X509Certificate();
Instanciar
GregorianCalendar date = (GregorianCalendar)Calendar.getInstance();
x509cert.setValidNotBefore(date.getTime());
date.add(Calendar.MONTH, p_duracao);
x509cert.setValidNotAfter(date.getTime());
Definir
data de
validade
Criar Certificado (Passo 2 de 2)
x509cert.setIssuerDN(p_certCA.getSubjectDN());
Quem assina
o certificado
Name subject = new Name();
subject.addRDN(ObjectID.country, p_pais);
subject.addRDN(ObjectID.organization, p_organization);
subject.addRDN(ObjectID.organizationalUnit, p_organizationUnit);
Informação
sobre o titular
do certificado
subject.addRDN(ObjectID.commonName, p_nome);
x509cert.setSubjectDN(subject);
x509cert.setSerialNumber(p_serial);
Nº série
x509cert.setPublicKey(cliPub);
Chave publica
x509cert.sign(AlgorithmID.sha1WithRSAEncryption, p_mypri);
Assinar o
certificado
Validar Certificado
Validar cadeia de certificados
Verificar que não está na CRL
Verificar o resultado do pedido OCSP
1.
2.
3.
•
•
•
Good
Revoked
Unknown
Validar cadeia de certificados
…
//Construir o ramo de certificados p_Array_cert
…
SimpleChainVerifier scv = new SimpleChainVerifier();
scv.addTrustedCertificate( p_trusted_cert );
if (scv.verifyChain( p_Array_cert ) ) {
{
return true;
}
else
{
return false;
}
Instanciar
Definir os certificados
de confiança
Verificar a cadeia de
certificados
(Datas, assinaturas,
etc.)
Conclusões
Permite a escolha das implementações mais
convenientes
As principais técnicas criptográficas estão
contempladas, permitindo criar qualquer tipo
de aplicação segura
Necessário perceber como funcionam
algumas técnicas criptográficas
Nível de detalhe
Permite grande controlo
Pode originar falhas de segurança graves
MSDPA-0607
Java Cryptography Architecture
(JCA)
Segurança e Privacidade em
Sistemas de Armazenamento
e Transporte de Dados
Rui Manuel C. O. Afonseca