Tutorial HTTPS/SSL no JBoss AS 7

Oi novamente a todos!

Para esse artigo vou falar como habilitar o uso de SSL no JBoss 7. Isto porque as informações disponíveis na internet são bem confusas e fragmentadas: alguns links dão informações incompletas, outros informações desatualizadas, etc. Sendo mais específico, vou abordar as versões AS 7.1.2 e/ou EAP 6.0. Acredito que não deve ser muito diferente para as versões superiores, inclusive para o JBoss 8 (WildFly).

Vou começar fazendo uma pequena introdução à criptografia assimétrica, SSL e também da ferramenta keytool disponível no JDK. Quem já domina esses tópicos e quer somente saber como configurar o JBoss, pode ir direto ao final do artigo.

Criptografia Assimétrica

A criptografia assimétrica também é conhecida como “public-key cryptography“, traduzindo literalmente: criptografia de chave pública. Isso se dá pelo fato de que nessa classe de algoritmo nós teremos duas chaves distintas: uma pública e uma privada (secreta).

Para colocar em perspectiva a necessidade de duas chaves, vamos imaginar o cenário mais simples. Vamos supor que você deseja enviar uma mensagem secreta para alguém. Uma mensagem codificada. A primeira opção seria usar uma chave (uma senha) para criptografar o texto, e em seguida fornecer essa mesma senha para todas as pessoas que você deseja que consigam ler o seu texto criptografado. Esse tipo de criptografia, com uma única chave, chama-se criptografia simétrica:

cripto-simetrica

Apesar de mais simples essa abordagem tem uma fragilidade óbvia: Se qualquer uma das pessoas envolvidas deixar que a chave seja roubada, ou mesmo quebrar sua confiança e contar a chave para terceiros, o segredo estará para sempre comprometido.

Para fins de comunicação segura pela internet, onde você muitas vezes não conhece formalmente com quem vai se comunicar, a criptografia simétrica não é adequada. Não seria possível usar uma única chave para criptografar mensagens entre o seu browser e um servidor remoto, não seria possível fazer essa troca, sem que a própria mensagem de “troca da chave” fosse feita de maneira limpa, sem criptografia. Portanto, não segura. O que adiantaria criptografar a comunicação entre cliente-servidor com uma chave que foi trocada de maneira não criptografada e que pode potencialmente ter sido interceptada?

Nesse cenário que entra a criptografia assimétrica. As duas chaves desse modo de criptografia, a pública e a privada, tem uma relação bem interessante: Qualquer mensagem criptografada com uma será somente descriptografada com a outra. É por causa dessa relação “promíscua” que se usa sempre uma das chaves como sendo pública e outra como privada.

Pensem bem: Se você possui duas chaves A e B com a garantia matemática de que qualquer mensagem criptografada com uma só poderá ser lida com a ajuda da outra, faz todo sentido do mundo que você distribua uma delas, a pública, para todos os seus contatos que desejam se comunicar secretamente com você. Eles usariam a chave A, a pública, para codificar a mensagem, e somente você que possui outra chave, a B, conseguiria decodifica-la.
Nesse caso, a chave que será usada como pública pode ser distribuída livremente sem preocupação, já que o “segredo” só pode ser desfeito com a chave privada que você claro vai fazer questão de nunca entregar para ninguém.

cripto-assimetrica

Alguém mais atento pode estar se perguntando: “Ótimo se meus contatos podem codificar as mensagens que desejam me enviar com a minha chave pública. Mas como eu poderia fazer para responder também de maneira secreta?? Se a minha resposta for codificada com a minha chave privada, qualquer pessoa que possui minha chave pública vai poder ler. Se usar a minha pública, somente eu mesmo conseguirei!”

Para resolver esse problema poderíamos usar duas estratégias: A primeira delas seria exigir que todos os seus contatos também possuíssem um par de chaves pública/privada e antecipadamente forneçam suas chaves públicas para você. Assim todos possuem as chaves públicas uns dos outros, e sempre que um quiser direcionar uma mensagem secreta a alguém específico, é só usar a chave pública daquele contato para codificar.

A segunda estratégia é a mesma usada pelo protocolo SSL que falaremos em seguida: Se na comunicação somente você possui um par de chaves público/privada, é só pedir para que o seu contato envie para você uma terceira chave, simétrica, criptografada com a sua chave pública! Diferente do primeiro cenário que discutimos sobre chaves simétricas, nesse caso a chave simétrica pôde ser transferida entre os dois pares também de maneira segura, criptografada, pois ela própria foi codificada com a chave pública que você distribuiu. Esse ciclo então se repetiria com todos os contatos que você fosse se comunicar. Cada um deles enviaria uma chave simétrica diferente de maneira codificada com sua chave pública para que você pudesse responde-los de volta.

HTTPS/SSL

Esse processo inicial de “troca de chaves” descrito acima é tecnicamente chamado de handshake. Depois que ele ocorre, o restante da comunicação entre os dois pares é feita somente usando a chave simétrica que foi fornecida pela parte que não possuía o par de chaves pública/privada.

Traduzindo essa situação para o mundo real, nós meros usuários mortais fazemos o papel da pessoa que não tem par de chaves assimétricas, enquanto as organizações e seus super servidores fazem o papel de quem as possui. Todo mundo aqui já deve ter acessado um site via https: bancos, gmail, facebook, etc. E é bem provável que nenhum de vocês nem soubessem que existem chaves sendo trocadas. Toda essa mágica é feita de maneira automática pelos browsers e os servidores:

Handshake SSL

Handshake SSL

A figura acima é possível ter uma idéia resumida de como o processo de negociação de chaves ocorre, o handshake, e nela também é possível perceber alguns termos que não usamos ainda: certificados e autoridades certificadoras (do inglês “certificate authority”, ou simplesmente “CA”).

O certificado é como se fosse uma carteira de identidade que possui sua chave pública. É esse certificado que você vai enviar para os contatos com quem deseja comunicar-se de maneira segura. Além de possuir a sua chave pública usada para criptografar as mensagens, o certificado também é uma maneira de identificar unicamente o seu dono. Ora, aquela chave pública só pode pertencer a quem possui a chave privada correspondente.

Infelizmente a comunicação digital é um pouco mais complexa. Não é como se você estivesse conhecendo alguém pessoalmente onde você ve a cara e o coração de quem está exibindo a identidade (certificado). Quando você acessa um site dito seguro, quem pode garantir que aquele certificado é realmente de quem está dizendo que é? Hacks mais elaborados podem fazer com que você acesse um site falso e receba um certificado falso, e acabe se comunicando de maneira segura porém com um impostor.

É ai que entram as autoridades certificadoras, como VeriSign, GlobalSign e etc. Uma vez que é possível atestar que uma chave dita pública só pode ter sido gerado a partir de sua chave privada correspondente, é a autoridade certificadora que garante que uma chave pública pertence a João ou Maria. Então para ter um certificado confiável, você tem que se “cadastrar” junto a essas entidades. Elas vão conferir seus dados e colocar um “selo de aprovação” no seu certificado.

É por isso que alguns sites seguros que nós acessamos apresentam uma mensagem de alerta indicando que aquele certificado não é confiável, isto é, não foi atestado por uma autoridade certificadora e exige intervenção manual do usuário para continuar. Esse “selo de aprovação” na verdade também é uma assinatura da CA, mas não vou entrar nesses detalhes de autoridades certificadoras e cadeia de confiança. Para fins de desenvolvimento somente, você não vai precisar assinar seus certificados junto a uma CA. Somente quando seu sistema for entrar em produção.

Keytool

Antes que você pense que para adquirir um par de chaves assimétricas você precise de um cartão de crédito e uma conta no ebay, vou demonstrar aqui como fazemos parar gerar essas chaves usando uma ferramenta que é distribuída junto com o JDK: keytool.

Dentro do diretório “JAVA_HOME/bin”, na sua instalação do JDK, além dos programas javac, java e etc também tem o tal do keytool. É um programa de linha de comando, então todos os comandos abaixo precisam ser executados dentro do diretório onde o keytool encontra-se, o diretório “bin” do seu JDK. Quem estiver com a variável PATH configurada corretamente não vai precisar disso, mas esse assunto foge do nosso escopo.

Na linha de comando, executem o comando abaixo:

keytool -genkey -alias exemplo -keyalg RSA -keystore exemplo.keystore
  • -genkey: sinaliza que um par de chaves deve ser gerado.
  • -alias: o apelido que vamos dar as nossas chaves, para que possam ser referenciadas posteriormente. Aqui escolhemos “exemplo”.
  • -keyalg: o algorítmo que será utilizado para geração das chaves, escolhemos “RSA”.
  • -keystore: o arquivo onde as chaves serão armazenadas. Entenda como keystore sendo o “cofre” que armazena as chaves. Como veremos a seguir o keystore só é acessado com uma senha. No nosso caso escolhi um arquivo “exemplo.keystore”, que vai ser criado no diretório onde executamos o comando keytool, mas poderia ser em qualquer lugar.

NOTA: A documentação completa do comando keytool pode ser encontrada nesse link aqui.

Após o executar comando você terá que responder um questionário como mostra a imagem abaixo:

keytool

As informações informadas no questionário acima são as informações que vão constar no seu certificado. Claro que se estivéssemos criando um certificado real para ambiente de produção, todas as informações seriam importantes. Como nesse caso é somente um certificado para ambiente de desenvolvimento, existem 3 informações que são fundamentais:

  • Keystore password: Essa é a senha que vai ser usada para acessar o seu “cofre”, a keystore. Essa senha terá que ser informada depois na hora de configurar o JBoss ou para fazer qualquer alteração no seu par de chaves.
  • First and last name: Apesar de parecer uma pergunta inocente sobre qual seu nome, aqui deve ser informado na verdade o endereço do seu site. Exemplo: http://www.meusite.com. No nosso caso usamos simplesmente localhost.
  • Key password for <example>: Assim como existe uma senha para acessar o keystore, também pode haver uma segunda senha para acessar especificamente o par de chaves com o alias “exemplo”. Um keystore pode conter vários pares de chave diferentes, então pode haver uma senha para cada um deles. Por fim de simplicidade, eu usei a mesma senha do keystore.

Pronto. Depois de concluído o questionário o par de chaves auto assinado estará criado no keystore “exemplo.keystore”. A seguir iremos configurar esse keystore no JBoss.

Antes de proseguir gostaria de mostrar um último comando usando o keytool, somente a título de curiosidade. Eu comentei no início do artigo que é comum alguém distribuir sua chave pública (seu certificado) a diferentes contatos. Para isso ser possível, é preciso executar o comando “export” usando o programa keytool:

keytool -export -alias exemplo -keystore exemplo.keystore -file certificado.cer

Você terá que informar a senha do keystore e pronto. Um arquivo certificado.cer será criado. E esse arquivo é que deve ser distribuído como sendo sua chave pública. Nunca caia na tentação de entregar o arquivo do seu keystore pra ninguém. Lembre-se que ele guarda também sua chave privada, e ela jamais deve ser compartilhada! OBS: Esse último passo para exportar um certificado não é necessário para configuração de HTTPS/SSL no JBoss.

Configuração JBoss

Como eu disse no início, essa configuração foi testada no JBoss AS 7.1.2 que é o mesmo JBoss EAP 6.0. Acredito que em versões superiores seja a mesma coisa ou bem parecido, inclusive no JBoss 8 Wildfly. Eu vou demonstrar aqui a configuração no modo standalone usando o profile default, isto é, usando o arquivo standalone.xml. Para fazer em diferentes profiles ou no modo domain é basicamente a mesma coisa, basta alterar o subsystem web, presente em todos os arquivos de configuração: domain.xml, standalone-full.xml, etc.

Não vou explicar novamente os passos mencionados nas seções anteriores do artigo. Caso não entenda o que está sendo feito aqui, recomendo ler desde o início.

PASSO 1: Criar o par de chaves na máquina local usando o keytool.

keytool -genkey -alias exemplo -keyalg RSA -keystore exemplo.keystore

PASSO 2: Abra o arquivo de configuração “JBOSS_HOME/standalone/configuration/standalone.xml” e procure o web subsystem, cujo trecho deve ser igual ao exibido abaixo:

<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    <virtual-server name="default-host" enable-welcome-root="true">
        <alias name="localhost"/>
        <alias name="example.com"/>
    </virtual-server>
</subsystem>

Como o trecho acima mostra, só existe um connector HTTP configurado. Nós vamos adicionar mais um, como mostram as linhas destacadas abaixo:

<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
        <ssl name="https" key-alias="exemplo" password="123456" certificate-key-file="/Users/fulano/exemplo.keystore"/>
    </connector>
    <virtual-server name="default-host" enable-welcome-root="true">
        <alias name="localhost"/>
        <alias name="example.com"/>
    </virtual-server>
</subsystem>

Das informações acrescidas acima, três delas nos informamos no momento da criação das chaves (observar linha 4): o alias, a senha do keystore e o caminho dele no disco.

PASSO 3: Para testar inicie o JBoss e acesse o endereço https://localhost:8443. Você deve receber um aviso pelo fato do certificado não ser confiável, mas clique para prosseguir e a página inicial do JBoss deve aparecer normalmente.

Dúvidas, críticas ou sugestões, deixem nos comentários! Até a próxima! 🙂

10 thoughts on “Tutorial HTTPS/SSL no JBoss AS 7

  1. Olá Rodrigo Uchôa. Parabéns pelo Post ! Muito informativo e útil. Agradeceria se pudesse olhar o que está acontecendo: ao gerar o arquivo “exemplo.keystore” e configurar o jboss, tento acessar a aplicação e o firefox mostra a seguinte mensagem [O SSL recebeu uma chave fraca e efêmera Diffie-Hellman na mensagem de handshake da chave do servidor de troca. (Código do erro: ssl_error_weak_server_ephemeral_dh_key) ], o que foi que esqueci ? Obrigado.

    • Oi!

      Minha primeira tentativa seria algo como “c:/exemplo/projetos/algum-lugar/arquivo.key”. Usando sempre uma única “/” como separador. E não “\”, como normalmente são os paths windows.

    • Oi novamente!

      Então, difícil te ajudar sem ter mais detalhes e sem ver como ta configurado o seu ambiente. O que posso sugerir e você fazer todos os passos novamente pra garantir que não esqueceu de nada.

      Abraço!

  2. Boa tarde Rodrigo,

    Eu fiz a configuração, e quando vou abrir https://localhost:8443 o navegador faz o download.
    A porta 8443 está aberta no servidor.
    Você pode me ajudar, pois eu tenho que configurar o ssl para o jboss 4 e estou testando com o jboss 7 porque não consegui no jboss 4, pois este é a versão homologada pelo ERP, e se conseguir no jboss 7 tem como argumentar com o software.

    • Oi Aguiberto!
      Realmente fica difícil te ajudar sem ter acesso ao que você está fazendo.

      A sugestão que posso dar é pra vc baixar um jboss “virgem”, de maneira a garantir que ninguem tenha mexido nele anteriormente, e tentar novamente.

      Abraço!

  3. Boa tarde,

    Parabéns pelo artigo, muito esclarecedor, aqui na empresa onde trabalho temos um WildCard registrado de forma que contemple qualquer aplicação da empresa, o pessoal de TI me enviou o Certificado SSL para que eu habilite o HTTPS no WIldfly, é necessário que ele me envie o keystore com a chave privada e a senha também para habilitar o HTTPS?

    • Oi Eder! (perdao pela falta de acentos pois meu teclado aqui nao aceita portugues-br)

      Vou direto ao ponto primeiro: Sim, o Wildfly precisa ter acesso aos dois, a chave privada e a chave publica (certificado). Normalmente, se for um keystore criado usando o keytool da JVM, os dois estao em um unico arquivo. Mas nao eh obrigatorio. Eu sinceramente nao sei aqui de cabeca o que seria necessario pra configurar o Wildfly com arquivos diferentes, entao espero que voce tenha so um unico keystore 🙂

      Se voce olhar em uma das imagens do artigo, voce vai ver que durante o handshake o cliente envia para o servidor uma chave simetrica temporaria, e criptografa essa chave com a chave publica que ele recebeu do servidor anteriormente. O servidor so vai conseguir descriptografar essa mensagem se ele tiver com a chave privada correspondente.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s