Segurança em Java Carlos Bazilio Depto de Ciência e Tecnologia Pólo Universitário de Rio das Ostras Universidade Federal Fluminense Segurança • Alguns conceitos: – Criptografia simétrica x assimétrica (método que utiliza a mesma chave – simétrica - ou chaves diferentes – assimétrica - na cifração e decifração) – Criptografia de chave pública – Assinatura Digital – Autoridade Certificadora (CA – Entidade responsável por garantir a validade das chaves públicas) – Certificado (chave pública + chave de uma CA) – Keystores (BD de chaves criptográficas) Criptografia Assimétrica Assinatura Digital Assinatura Digital • Idéia básica, supondo que se deseja enviar um documento de forma segura: – Você assina o documento usando alguma de suas chaves privadas – Envia o documento assinado para o destinatário – Disponibiliza ao destinatário sua chave pública – O destinatário usa sua chave pública para se certificar que foi você quem a assinou • Como o destinatário se certifica que a chave pública é autêntica? – Usualmente, a chave pública é disponibilizada juntamente com a chave de alguma Autoridade Certificadora (CA), o que chamamos de certificado Assinatura em Mensagem sem Privacidade Assinatura em Mensagem com Privacidade Autoridade Certificadora • Uma Autoridade Certificadora é uma entidade, pública ou privada, que estabelece previamente a identidade do futuro portador do certificado digital (pessoa física ou jurídica), por meio dos documentos necessários, e emite esse certificado (Definição da ICP: https://www.icpbrasil.gov.br) • Exemplo: VeriSign (http://www.verisign.com.br/) Autoridade Certificadora Certificados • Um certificado digital é um documento eletrônico, assinado digitalmente por uma terceira parte confiável, que associa uma entidade (pessoa, processo, servidor) a uma chave pública • Na prática, o certificado digital funciona como uma carteira de identidade virtual que permite a identificação segura de uma mensagem ou transação na rede Certificados • Um certificado contém: – Uma chave pública – Informações do dono do certificado: nome, organização, cidade, país, etc – Uma assinatura digital da certificadora – Informações da certificadora • Um receptor pode checar um certificado analisando sua assinatura digital com a chave pública da certificadora • Esta chave também pode estar armazenada num certificado, o qual cria uma recorrência Cadeia de Certificados • Relação de confiança entre autoridades certificadoras (CA) • Também chamada de hierarquia de certificados • Em termos práticos, a confiança numa CA implica na confiança nas CAs acima hierarquicamente dessa Listando Certificados • Certificados podem fazer parte do SO, dos navegadores ou de Java • No Firefox: – Tools > Options > Advanced > View Certificates • No IE: – Tools > Internet Options > Content > Certificates • Windows: – Start > Control Panel > Internet Options > Content > Certificates • Em Java: – WinNT\Profiles\<usuário>\.keystore (certificados) – <Java>\jre\lib\security\cacerts (autoridades certificadoras) Impressão Digital de Certificados • Fingerprints Certificates • Quando uma cadeia segura não é encontrada, a impressão digital do certificado pode ser calculada • Cada impressão digital é um pequeno número que única e confiavelmente identifica um certificado (tecnicamente, é um valor hash) • Daí basta comparar a impressão digital calculada com uma fornecida pelo proprietário do certificado Keystores • Bancos de dados protegidos por senha que armazenam chaves privadas e seus correspondentes certificados • Um keystore pode ter diversas entradas, cada entrada identificada por um alias • Certificados em keystores são chamados de certificados confiáveis (trusted certificates) • O JDK disponibiliza uma ferramenta chamada keytool para manipulação de keystores Segurança em Java • Inclui um vasto conjunto de APIs, ferramentas e implementações • Estas APIs compreendem: – – – – – Criptografia (JCA) Infra-estrutura de chave pública (PKI) Comunicação segura (JSSE) Autenticação e controle de acesso (JAAS) Assinatura digital de XML • Como na maioria da arquitetura Java, estas APIs são generalizadas de forma a se trabalhar com versões de diferentes fabricantes Keytool • Ferramenta utilizada para gerenciar um keystore (base de dados de chaves criptográficas, cadeias de certificados e certificados confiáveis) • Esta é distribuída junto com o kit de desenvolvimento Java – JDK (http://java.sun.com/javase/6/docs/technotes/tools/windo ws/keytool.html) • Com ela podemos: – Criar chaves privadas e os correspondentes certificados públicos – Gerar solicitações de certificados, os quais podem ser enviados às autoridades certificadoras – Importar certificados emitidos pelas certificadoras – Gerenciar o Keystore • Estas atividades também podem ser realizadas pela API da linguagem (pacote java.security) Gerando Chaves com o Keytool <JAVA_HOME>/bin/keytool –genkey –alias sirius –keyalg RSA • A execução deste comando irá gerar um arquivo denominado “.keystore” em seu diretório home (ex.: “..\Documents and Settings\bazilio\.keystore”); • Outras opções podem ser consultadas através do comando “keytool –help”; Gerando Requisição de Certificado para CA <JAVA_HOME>/bin/keytool –certreq –alias sirius – file pedido.csr • Este comando gera uma requisição de certificado a ser enviada para um CA e coloca num arquivo denominado “pedido.csr” (CSR – Certification Signing Request) • A resposta da CA será um certificado, assinado por ela, autenticando a chave pública fornecida anteriormente (gerada pelo comando keytool do slide anterior) • Essa resposta usualmente é off-line e pode ser retornado uma cadeia de certificados Importando o Resultado de uma Requisição • Suponha que a resposta seja recebida num arquivo chamado “resposta.cer” <JAVA_HOME>/bin/keytool –importcert – alias siriusca –file resposta.cer • Este comando cria um certificado confiável no keystore com os dados do arquivo “resposta.cer” e associa ao alias “siriusca” Exportando um Certificado <JAVA_HOME>/bin/keytool -exportcert alias siriusca –file minha_chave_ca.cer • Exporta a entrada autenticada pela CA para o arquivo “minha_chave_ca.cer” Exemplos em Java • Geração de Assinatura Digital – Geração das chaves – Geração da assinatura digital usando a chave privada – Exportação da chave pública e da assinatura para arquivos • Verificação da Assinatura Digital – Importação da chave pública – Verificação da autenticidade da assinatura SSL • SSL (Secure Socket Layer) é uma tecnologia que permite servidores web e navegadores se comunicarem de forma segura • Com SSL, as mensagens trafegadas são cifradas e decifradas no lado do cliente e no lado do servidor • Quando um cliente inicia uma comunicação com um servidor através de uma conexão segura, este envia um certificado “se identificando” • A tecnologia também permite que o servidor requisite um certificado do cliente (autenticação do cliente), embora isto seja pouco comum SSL no Tomcat • Configurar conexões seguras no Tomcat só faz sentido quando este está executando como um servidor stand-alone • Quando é utilizado um servidor como Apache ou IIS para recebimento das requisições, este servidor faria o processo de cifragem/decifragem • Assim, o Tomcat só teria o papel de ser um contêiner para servlets/jsps SSL no Tomcat • Para oferecermos conexões seguras no Tomcat precisamos de um certificado, o qual será enviado por ele no início de uma conexão segura • Para tal podemos utilizar a ferramenta keytool • Neste caso, o parâmetro alias precisa ser “tomcat” e a senha padrão esperada pelo Tomcat é “changeit” • Ambas as senhas do keystore e do certificado precisam ter o mesmo valor SSL no Tomcat <JAVA_HOME>/bin/keytool –genkey –alias tomcat –keyalg RSA • Este comando irá gerar o arquivo .keystore no diretório “..\Documents and Settings\usuário\.keystore” • Observe, entretanto, que um certificado gerado com a ferramenta keytool não deveria ter a mesma confiabilidade de um certificado emitido por uma CA • Esses certificados são chamados de self-signed • Os navegadores normalmente alertam o usuário no recebimento de um certificado como esses, o qual poderia ser enviado por um servidor web não confiável SSL no Tomcat • Como o processo de cifragem/decifragem é caro, deve ser utilizado de forma inteligente • Ou seja, só este tipo de conexão deve ser definida para partes do site que transmitem dados confidenciais, e não para todo o site • Estas páginas passarão a ser acessadas usando https • A porta TCP padrão de conexões https é 443 • O Tomcat utiliza a porta 8443 SSL no Tomcat • A versão corrente do Tomcat trabalha com keystores no formato JKS (Java Keystore), PKCS11 e PKCS12 (Public Key Cryptography Standards 11 e 12) – http://en.wikipedia.org/wiki/PKCS • Após a geração do certificado, precisamos configurar o Tomcat para permitir conexões seguras • Para tal, modificaremos o arquivo de configuração “<tomcat>/conf/server.xml” SSL no Tomcat • No arquivo server.xml devemos retirar o comentário do conector 8443 e modificá-lo da seguinte forma: <Connector port="8443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" keystoreFile="c:\Java\Tomcat6\.keystore" keystorePass="changeit" clientAuth="false" sslProtocol="TLS"/> • Após atualizar o arquivo, basta reiniciar o Tomcat e digitar o seguinte endereço no browser: https://localhost:8443/ Autenticação no Tomcat • Aplicações web são hospedadas no Tomcat no diretório: <tomcat>/webapps • Usualmente, a configuração de uma aplicação reside num arquivo denominado descritor de implantação: <tomcat>/webapps/app/WEBINF/web.xml • Dentro do elemento raiz <webapp /> 2 elementos são importantes: – <login-config />: indica o tipo de autenticação utilizada – <security-constraint />: indica que parte da aplicação deve ser resguardada e quem tem acesso Autenticação Básica no Tomcat <web-app> ... <login-config> <auth-method>BASIC</auth-method> <realm-name>Área de Testes</realm-name> </login-config> </web-app> • Indica que a aplicação exige um tipo básico de autenticação • O elemento <login-config /> deve ser colocado dentro do elemento <webapp /> • Ainda deverá ser fornecido as partes da aplicação que deverão se resguardadas e que conteúdos (slides à seguir) • Os métodos possíveis de autenticação são: BASIC, DIGEST, FORM e CLIENT-CERT • A autenticação básica solicita apenas um usuário e senha válidos no servidor (tomcat) – por exemplo, através do arquivo <tomcat>/conf/tomcat-users.xml Autenticação de Resumo no Tomcat • Cliente • 1. Cliente solicita um recurso protegido • 3. O usuário insere o nome e a senha dele • 4. A máquina do cliente cria um hash das informações: (nome + senha + url + método http + nonce) Servidor 2. O servidor cria o nonce aleatório e o envia ao cliente 5. O servidor valida o hash criando seu próprio para verificar se ele corresponde ao do cliente 6. Envia o recurso requisitado ao cliente ou uma página de erro Autenticação de Resumo no Tomcat • Modificação do arquivo web.xml <web-app> ... <login-config> <auth-method>DIGEST</auth-method> <realm-name>Área de Testes</realm-name> </login-config> </web-app> Autenticação de Formulário no Tomcat • Personalização da autenticação através do fornecimento de uma página de login/senha própria; • Além disso, também deve ser fornecida uma página erro; • A construção do formulário deverá conter campos com nome padrão, já que é o Tomcat que valida o usuário: – j_security_check para o nome da ação; – j_username para o nome do usuário; – j_password para senha. Autenticação de Formulário no Tomcat <html> <head> <title>Formulário de Login</title> </head> <body> <h1>Por favor, autentique-se:</h1> <form action="j_security_check" method="post"> Usuário: <input type="text" name="j_username" /><br /> Senha: <input type="password" name="j_password" /><br /> <input type="submit" value="Envie" /> </form> </body> </html> Autenticação de Formulário no Tomcat • Modificação do arquivo web.xml <web-app> ... <login-config> <auth-method>FORM</auth-method> <realm-name>Testes de Formulário</realm-name> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/erro.html</form-error-page> </form-login-config> </login-config> </web-app> Autenticação SSL de 2 vias no Tomcat <login-config> <auth-method>CLIENT-CERT</auth-method> <realm-name>Área de Testes</realm-name> </login-config> • Neste método, ambos servidor e cliente precisam apresentar certificados válidos para autenticação • Além desta configuração precisamos realizar outros 2 passos para completar esta configuração: – Definir o elemento <user-data-constraint /> (a ser visto a seguir) para alguma porção da sua aplicação (configuração para HTTPS) – Prover algum certificado válido, no lado do cliente, para testes Autenticação no Tomcat • Para indicarmos que partes da aplicação devem ser resguardadas utilizamos o elemento <security-constraint />, sub-elemento de <web-app> <security-constraint> <web-resource-collection> <web-resource-name>Área Segura</web-resourcename> <url-pattern>/seg/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>tomcat</role-name> </auth-constraint> </security-constraint> Autenticação no Tomcat • Descrição dos sub-elementos de <security-constraint />: – <url-pattern />: indica o subdiretório raiz à partir do qual a autenticação é exigida – <http-method />: indica sobre qual método http a autenticação é exigida – <auth-constraint />: indica que papéis (sub-elemento <role-name />) de usuários têm acesso ao conteúdo indicado em <urlpattern /> • Observe que os elementos <security-constraint />, <urlpattern />, <http-method /> e <role-name /> podem ocorrer de forma repetida; isto facilita a configuração de porções da aplicação que possuem regras de autenticação similares Configuração da Aplicação para HTTPS • Para que os dados entre cliente e servidor sejam enviados de forma segura, criamos o elemento <user-data-constraint /> como subelemento de <security-constraint /> <security-constraint> ... <user-data-constraint> <transport-guarantee> CONFIDENTIAL </transport-guarantee> </user-data-constraint> </security-constraint> Configuração da Aplicação para HTTPS • As opções para a tag transport-guarantee são: – CONFIDENTIAL: os dados devem ser transmitidos sem interceptação – INTEGRAL: os dados devem ser transmitidos sem interceptação e preservando a integridade (similar ao resumo) – NONE: nenhuma garantia é exigida. • Tanto CONFIDENTIAL quanto INTEGRAL resultam no uso de SSL Autenticação usando SGBD via JDBC no Tomcat • Copiar driver JDBC para a pasta <tomcat>/lib/ e reiniciar o Tomcat • Criar 2 tabelas no SGBD escolhido: Autenticação usando SGBD via JDBC no Tomcat • Há 2 opções de configuração da aplicação: – <tomcat>/conf/server.xml (configuração global): o elemento xml fornecido à seguir deve ser colocado dentro do elemento <Engine /> – <tomcat>/webapps/app/METAINF/context.xml (configuração local): o elemento xml fornecido à seguir deve ser colocado dentro do elemento <Context /> Autenticação usando SGBD via JDBC no Tomcat • Exemplo utiliza o MySQL • Descrição dos atributos à seguir Autenticação usando SGBD via JDBC no Tomcat Referências • http://jf.eti.br/autenticando-aplicacao-webcom-tomcat-5-e-banco-de-dados/ – Tutorial de configuração do Tomcat com SGBDs