Tutorial mostrando como fazer conexão segura de uma aplicação Web feita em Java com autenticação usando certificados digitais. Como certificado digital será utilizado e-CPF/e-CNPJ emitidos pela estrutura de chaves públicas ICP-Brasil. Como servidor usaremos o Tomcat. O certificado do servidor será auto assinado.
Usando a ferramenta Keytool, crie uma chave privada RSA para o servidor:
# keytool -genkey -alias tomcat -keyalg RSA
Informe os parâmetros que o keytool pedirá para criar o certificado. Será necessário informar uma senha. Nesse tutorial sempre será usado a palavra 'password'.
Depois, auto assine o certificado criado:
# keytool -selfcert -alias tomcat
Liste seu certificado criado executando o comando:
# keytool -list
Agora abra o arquivo de configuração, no Tomcat é o server.xml. Configure um Connector para usar SSL e requisitar certificados digitais da máquina cliente:
<Service name="Catalina">
...
<Connector acceptCount="100" connectionTimeout="20000"
executor="tomcatThreadPool" maxKeepAliveRequests="15" port="8080"
protocol="HTTP/1.1" redirectPort="8443" />
<Connector port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${user.home}/.keystore" keystorePass="password"
clientAuth="true" sslProtocol="TLS"/>
...
</Service>
O parâmetro clientAuth é o que faz o SSL requisitar certificados digitais. Conforme mostra na documentação do Tomcat, esse valor pode ser true, false ou want.
Instalar no key store utilizado pelo Tomcat as autoridades confiáveis. Para isso, baixe os arquivos das ACs no repositório da autoridade raiz brasileira.
Execute o comando no shell:
# keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file certificadoDaAc.cer -alias NOME_DA_CA
A senha padrão desse repositório é changeit.
Após importar os certificados, se fizer:
# keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
Será listado os certificados confiáveis de autoridades instalados.
Instale seu certificado digital no navegador e teste iniciando o Tomcat e abrindo a página https://localhost:8443. Se você tiver um certificado digital emitido por alguma autoridade confiável cadastrada no keystore do Java, irá aparecer uma janela para que você escolha o certificado digital e digite sua senha.
Note que se você não tiver instalado no navegador nenhum certificado digital válido, ou se tiver instalado algum vencido, ou de uma autoridade certificado não cadastrada, a página nem irá abrir.
Se tudo estiver correto e você visualizar a página, sua aplicação web já poderá ler os dados desse certificado digital após estabelecer a sessão.
Em Java, isso pode ser feito da seguinte maneira:
public class LerCertificado extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>ServletLerCertificado</title></head>");
out.println("<body>");
out.println("<p>Certificado digital:</p>");
//
String cipherSuite = (String) request
.getAttribute("javax.servlet.request.cipher_suite");
if (cipherSuite != null) {
java.security.cert.X509Certificate certChain[] = (java.security.cert.X509Certificate[]) request
.getAttribute("javax.servlet.request.X509Certificate");
System.out.println("Array size: " + certChain.length);
if (certChain != null) {
for (int i = 0; i < certChain.length; i++) {
String certInfo = "Client Certificate [" + i + "] = "
+ certChain[i].toString();
out.println(certInfo);
}
}
} else {
out.println("Cliente sem Certificado Digital");
}
//
out.println("</body></html>");
out.close();
}
Uma vez lido o certificado digital da sessão, tem-se acesso ao CPF ou CNPJ do dono do certificado, podendo assim utilizá-lo para validação na autenticação do usuário no sistema.
Projeto de exemplo no GitHub:
Para facilitar a leitura dos dados certificado digital, foi utilizado a biblioteca Boncy Castle.
Para ler o certificado digital do e-CPF/e-CNPJ, ou outro smart card qualquer, o processo é o mesmo. A diferença é que não é necessário instalar certificados digitais no navegador, basta instalar o driver de sua leitora de smart card, que caso forneça um certificado válido, irá abrir a mesma tela no browser pedindo que você escolha o certificado que irá usar para estabelecer a conexão.
Certificados digitais são maneiras muito seguras e confiáveis de trafegar dados na Web. Facilmente pode ser configurado nas aplicações. O SSL cuida de todo o resto.
Configurar o servidor
# keytool -genkey -alias tomcat -keyalg RSA
Informe os parâmetros que o keytool pedirá para criar o certificado. Será necessário informar uma senha. Nesse tutorial sempre será usado a palavra 'password'.
Depois, auto assine o certificado criado:
# keytool -selfcert -alias tomcat
Liste seu certificado criado executando o comando:
# keytool -list
Agora abra o arquivo de configuração, no Tomcat é o server.xml. Configure um Connector para usar SSL e requisitar certificados digitais da máquina cliente:
<Service name="Catalina">
...
<Connector acceptCount="100" connectionTimeout="20000"
executor="tomcatThreadPool" maxKeepAliveRequests="15" port="8080"
protocol="HTTP/1.1" redirectPort="8443" />
<Connector port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${user.home}/.keystore" keystorePass="password"
clientAuth="true" sslProtocol="TLS"/>
...
</Service>
O parâmetro clientAuth é o que faz o SSL requisitar certificados digitais. Conforme mostra na documentação do Tomcat, esse valor pode ser true, false ou want.
Passo dois: Instalar as autoridades CA (Certificate Authorities) confiáveis:
Instalar no key store utilizado pelo Tomcat as autoridades confiáveis. Para isso, baixe os arquivos das ACs no repositório da autoridade raiz brasileira.
Execute o comando no shell:
# keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file certificadoDaAc.cer -alias NOME_DA_CA
A senha padrão desse repositório é changeit.
Após importar os certificados, se fizer:
# keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
Será listado os certificados confiáveis de autoridades instalados.
Passo três: Ler o certificado digital da sessão
Instale seu certificado digital no navegador e teste iniciando o Tomcat e abrindo a página https://localhost:8443. Se você tiver um certificado digital emitido por alguma autoridade confiável cadastrada no keystore do Java, irá aparecer uma janela para que você escolha o certificado digital e digite sua senha.
Note que se você não tiver instalado no navegador nenhum certificado digital válido, ou se tiver instalado algum vencido, ou de uma autoridade certificado não cadastrada, a página nem irá abrir.
Se tudo estiver correto e você visualizar a página, sua aplicação web já poderá ler os dados desse certificado digital após estabelecer a sessão.
Em Java, isso pode ser feito da seguinte maneira:
public class LerCertificado extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>ServletLerCertificado</title></head>");
out.println("<body>");
out.println("<p>Certificado digital:</p>");
//
String cipherSuite = (String) request
.getAttribute("javax.servlet.request.cipher_suite");
if (cipherSuite != null) {
java.security.cert.X509Certificate certChain[] = (java.security.cert.X509Certificate[]) request
.getAttribute("javax.servlet.request.X509Certificate");
System.out.println("Array size: " + certChain.length);
if (certChain != null) {
for (int i = 0; i < certChain.length; i++) {
String certInfo = "Client Certificate [" + i + "] = "
+ certChain[i].toString();
out.println(certInfo);
}
}
} else {
out.println("Cliente sem Certificado Digital");
}
//
out.println("</body></html>");
out.close();
}
Uma vez lido o certificado digital da sessão, tem-se acesso ao CPF ou CNPJ do dono do certificado, podendo assim utilizá-lo para validação na autenticação do usuário no sistema.
Projeto de exemplo no GitHub:
Para facilitar a leitura dos dados certificado digital, foi utilizado a biblioteca Boncy Castle.
Leitoras de Smart Card
Para ler o certificado digital do e-CPF/e-CNPJ, ou outro smart card qualquer, o processo é o mesmo. A diferença é que não é necessário instalar certificados digitais no navegador, basta instalar o driver de sua leitora de smart card, que caso forneça um certificado válido, irá abrir a mesma tela no browser pedindo que você escolha o certificado que irá usar para estabelecer a conexão.
Conclusão
Certificados digitais são maneiras muito seguras e confiáveis de trafegar dados na Web. Facilmente pode ser configurado nas aplicações. O SSL cuida de todo o resto.
Veja também
References
- Cristiano Andrade Blog. Acessado em 30 de julho de 2010.
http://cristianosandrade.blogspot.com/20 10/03/extrair-dados- de-um-certificado-ic p.html
Sugiro criar um projeto web normal e fazer funcionar. Depois adicionar a segurança. Não sei o que pode ter ocasionado esse erro.
ReplyDeleteParabéns pelo post. Eu estava procurando uma direção sobre como implementar autenticação com certificados digitais. Me ajudou bastante.
ReplyDeleteValeu, obrigado!
DeleteCara, não estou conseguindo baixar seu projeto de exemplo no tal de minus.
ReplyDeleteTem ele hospedado em outro lugar?
Obrigado!
O minus.com realmente está com problemas. Obrigado por avisar.
DeleteEu alterei o post apontando para o caminho do projeto de exemplo no GitHub.
https://github.com/edpichler/Digital_Certificates_with_SSL_on_Tomcat
Olá estou com problemas para implementar no passo 3
ReplyDeleteErro:
type Status report
message /LerCertificado/servlet/main.java.br.com.mycompany.LerCertificado
description The requested resource is not available.
Poderia me dar uma direciontamento?
Grato,