Java Cryptography Architecture (JCA) 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 Exemplo Conclusões 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 SUN Provider IAIK Define abstractamente um serviço criptográfico (sem implementação). Providers Packages que fornecem implementações de serviços criptográficos. Provider SUN Provider fornecido por omissão. Provider IAIK 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 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 Cliente – Cliente Envelope Digital Cliente – Cliente Station-to-Station Cliente – Chat CA Chave Publica Servidor – Chat CA
Desenho Conceptual Interface Operacional Criptográfica Rede 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 “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 DH Melhora-mento
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(); BigInteger k = gy.modPow(x, dhsp.getP()); Determinar Chave K 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); Cipher enc = Cipher.getInstance("DES/ECB/PKCS5Padding","IAIK") enc.init(Cipher.ENCRYPT_MODE, sk); Cipher dec = Cipher.getInstance("DES/ECB/PKCS5Padding"); dec.init(Cipher.DECRYPT_MODE, sk); 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); Inicialização Assinar Cifrar Enviar
StationToStation (Passo 3 de 3) Ler o criptograma SealedObject sigXY2 = (SealedObject) ois.readObject(); byte[] assinaturaXY2 = (byte[]) sigXY2.getObject(dec); sig.initVerify(pub); sig.update(gx.toByteArray()); sig.update(gy.toByteArray()); if( sig.verify(assinaturaXY2) ) { return true; } else return false; Decifrar – Obter a assinatura Verificar assinatura
Certificados X.509 Autoridades de Certificação Clientes 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(); PrivateKey cliPri = clikp.getPrivate(); PublicKey cliPub = clikp.getPublic(); X509Certificate x509cert = new X509Certificate(); GregorianCalendar date = (GregorianCalendar)Calendar.getInstance(); x509cert.setValidNotBefore(date.getTime()); date.add(Calendar.MONTH, p_duracao); x509cert.setValidNotAfter(date.getTime()); Gerar par de chaves Instanciar Definir data de validade
Criar Certificado (Passo 2 de 2) Quem assina o certificado x509cert.setIssuerDN(p_certCA.getSubjectDN()); Name subject = new Name(); subject.addRDN(ObjectID.country, p_pais); subject.addRDN(ObjectID.organization, p_organization); subject.addRDN(ObjectID.organizationalUnit, p_organizationUnit); subject.addRDN(ObjectID.commonName, p_nome); x509cert.setSubjectDN(subject); x509cert.setSerialNumber(p_serial); x509cert.setPublicKey(cliPub); x509cert.sign(AlgorithmID.sha1WithRSAEncryption, p_mypri); Informação sobre o titular do certificado Nº série Chave publica Assinar o certificado
Validar Certificado Validar cadeia de certificados Verificar que não está na CRL Verificar o resultado do pedido OCSP 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
Java Cryptography Architecture (JCA) MSDPA-0607 Java Cryptography Architecture (JCA) Segurança e Privacidade em Sistemas de Armazenamento e Transporte de Dados Rui Manuel C. O. Afonseca