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