quinta-feira, 17 de setembro de 2009

Configurando SSL/TLS no JBoss/Tomcat

Segurança sempre soa como uma falácia na maioria dos projetos de software. É como aquele pessoal que não gosta ou não sabe testar: eles sabem que a coisa existe e que é preciso ou muito recomendável usar, mas no fim das contas dão de ombros e se funcionar, funcionou.

Isso acontece muito quando o âmbito é segurança. Qual cliente ou usuário não se preocupa com segurança? Ao menos um controle de acesso com autenticação através de usuário e senha eles sempre exigem. E qualquer desenvolvedor que se preze se preocupa com isso.

Quando pensamos em segurança em aplicações Java, temos que conhecer bem como funciona a arquitetura de segurança da plataforma Java, que é bem completa e útil. A divisão se dá em três "áreas" distintas, que são:

  • JCA (Java Cryptography Architecture): Define classes e interfaces que são responsáveis por trabalhar com criptografia e descriptografia de dados e informações;
  • JSSE (Java Secure Socket Extension): Usa a JCA para criar conexões seguras para troca de dados e informações;
  • JAAS (Java Authentication and Authorization Service): Responsável por autenticação e autorização nas aplicações Java.

Neste artigo vou abordar somente um pouco do JSSE. Para saber mais sobre JAAS veja no arquivo do blog.

O SSL (Secure Socket Layer) e o TLS (Transport Layer Security) são protocolos criptográficos usados para garantir a comunicação segura entre serviços de internet. Não vou entrar em detalhes sobre os protocolos e nem nas suas diferenças, para maiores informações sugiro esta leitura.

A necessidade fundamental de uma implementação com SSL é garantir a privacidade e a integridade dos dados trafegados entre as aplicações que estão se comunicando. E isso é realizado através da autenticação das aplicações e da utilização de algoritmo criptográfico nos dados que estão sendo trafegados.

Dizer isso é meio bonitinho mas ninguém consegue compreender como isso ocorre de verdade, o que acontece por "por baixo dos panos". Vamos imaginar um cliente utilizando um browser qualquer para acessar uma aplicação instalada num servidor JBoss, com certificado SSL implantado. Quando a comunicação entre eles é iniciada, o servidor envia uma chave pública ao browser, que usa esta chave para criar uma chave privada temporária que é enviada de volta ao servidor. Desta forma as duas partes, servidor e browser, usarão estas chaves para estabelecer uma comunicação segura. Para saber mais sobre chaves públicas, privadas, criptografia simétrica e assimétrica veja a minha apresentação sobre certificação digital.

Vamos então por a mão na massa e configurar a aplicação.

Criando as chaves

Usaremos o keytool para criar um keystore e nele armazenar as chaves.

keytool -genkey -keystore jeve.keystore -storepass jevepass -keypass jevepass -keyalg RSA -alias jeve_key -validity 3650 -dname "cn=Jeveaux,ou=Jeveaux,c=Vitoria,s=ES,c=BR"

Detalhamento do comando:

  • keytool: comando
  • -genkey: parâmetro para criação das chaves
  • -keystore: indica o caminho/nome do keystore (jeve.keystore)
  • -storepass: indica a senha do keystore (jevepass)
  • -keypass: indica a senha da chave (jevepass)
  • -keyalg: indica o algoritmo de criptografia utilizado (RSA)
  • -alias: indica o nome da chave a ser criada dentro do keystore (jeve_key)
  • -validity: Validade do certificado em dias (3650)
  • -dname "[...]": Informações do certificado (CN = nome comum, OU = unidade organizacional (departamento, divisão), O = nome da organização, L = nome da localidade (cidade), S = estado, C = código do país)

Próximos passos, informar ao JBoss/Tomcat onde está o keystore e qual chave usar.

Instalando as chaves

Basicamente temos que copiar o arquivo do keystore, gerado no passo anterior, para o JBoss. O ideal seria em:

$JBOSS_HOME/server/default/conf

Configurando o JBoss ou o Tomcat

Trabalharemos agora no arquivo server.xml para configurar qual keystore usar. Este é um arquivo de configuração do Tomcat.

Se você estiver usando JBoss:

$JBOSS_HOME/server/default/deploy/jbossweb.sar/server.xml

Se estiver usando Tomcat:

$TOMCAT_HOME/conf/server.xml

Procure por um comentário semelhante a este:

Haverá um trecho do arquivo comentado logo abaixo, vamos retirar os comentários e ativar este trecho de código. Ajustando as propriedades adequadas chegaremos em algo próximo disso:

<Connector protocol="HTTP/1.1" SSLEnabled="true"
port="8443" address="${jboss.bind.address}"
maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
emptySessionPath="true"
scheme="https" secure="true" clientAuth="false"
keystoreFile="${jboss.server.home.dir}/conf/jeve.keystore"
keystorePass="jevepass" sslProtocol = "TLS" />

Os pontos mais importantes são: port, keystoreFile e keystorePass, que são responsáveis por, respectivamente, definir a porta para utilização do SSL, qual o arquivo contém as chaves e qual a senha do arquivo que contém as chaves.

Neste ponto já conseguimos utilizar a aplicação através do protocolo HTTPS, basta acessar:

https://localhost:8443/aplicacao

Configurando a aplicação

Até aqui a aplicação está disponível tanto através de HTTP quando através de HTTPS. Em algumas situações isso é desejado, em outras não. Existem casos onde precisaremos que algumas partes ou módulos da aplicação só funcionem com HTTPS e outras situações que toda a aplicação responda somente sob HTTPS, e ambas são possíveis de serem atendidas, veremos.

        <security-constraint>
<web-resource-collection>
<web-resource-name>app-nameweb-resource-name>
<url-pattern>/*url-pattern>
web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIALtransport-guarantee>
user-data-constraint>
security-constraint>

Inserindo este trecho no seu web.xml nós faremos com que a aplicação inteira responda apenas sob protocolo HTTPS.

Importando um certificado válido

Tudo foi feito utilizando um certificado fictício e poderá correr assim durante o desenvolvimento, não há problema algum. Mas em produção este certificado terá o mesmo valor que uma nota de um cruzado novo. Então você ou sua empresa farão a aquisição de um certificado válido através de um autoridade certificadora e, quando isso ocorrer, importaremos o certificado válido para nosso keystore, utilizando a mesma ferramenta que usamos para criar o certificado anterior (keytool) vejamos:

keytool -import -alias jeve_key -keystore $JBOSS_HOME/server/default/conf/jeve.keystore -trustcacerts -file $ENDERECO_DO_CERTIFICADO_VALIDO/certificado_valido.cer

E, pronto, certificado válido importado e comunicação segura garantida.

NOTA importante :A senha do seu certificado deve ser a mesma senha do seu keystore. Se forem diferentes você vai tomar uma java.io.IOException: Cannot recover key! Mais

Fonte: http://imasters.uol.com.br/artigo/14188/seguranca/configurando_ssltls_no_jbosstomcat/

Informo que essa publicação é somente para armazenamento e informação particular, não tendo a intenção de divulgação pública.

Wilson Milagres