Introdução ao SSL em Java

Introdução ao SSL em Java

1. Visão geral

Neste tutorial, vamos apresentar SSL e explorar como podemos usá-lo em Java usando a API JSSE (Java Secure Socket Extension).

2. Introdução

Simplificando, osSecured Socket Layer (SSL) enables a secured connection between two parties, geralmente clientes e servidores.

O SSL fornece um canal seguro entre dois dispositivos que operam em uma conexão de rede. Um exemplo comum de SSL é permitir comunicações seguras entre navegadores e servidores da web.

Nesse caso específico, os navegadores da Web usarão conexões HTTPS (S, para Segurança) para acessar os recursos fornecidos por servidores da Web distintos.

SSL é necessário para apoiar os três princípios principais de segurança da informação:

  • Encryption: protege as transmissões de dados entre as partes

  • Authentication: certifique-se de que o servidor ao qual nos conectamos é realmente o servidor adequado

  • Data integrity: garantia de que os dados solicitados são efetivamente entregues

Java fornece várias APIs baseadas em segurança que ajudam os desenvolvedores a estabelecer conexões seguras com o cliente para receber e enviar mensagens em um formato criptografado:

  • Extensão de soquete seguro Java (JSSE)

  • Arquitetura de criptografia Java (JCA)

  • Extensão criptográfica Java (JCE)

Nas próximas seções, apresentaremos a extensão Secure Socket que o Java usa para permitir a comunicação segura.

3. API JSSE

As APIs de segurança Java usam o padrão de designFactory extensivamente.

De fato, tudo é instanciado usando uma fábrica no JSSE.

3.1. SSLSocketFactory

Ojavax.net.ssl.SSLSocketFactory é usado para criar objetosSSLSocket.

Esta classe contém três grupos de APIs.

O primeiro grupo consiste em um único método estáticogetDefault() usado para recuperar a instância padrão que, por sua vez, pode criar instâncias SSLSocket.

O segundo grupo consiste em cinco métodos que podem ser usados ​​para criar instânciasSSLSocket:

  • Socket createSocket (String host, porta interna)

  • Socket createSocket (String host, int port, InetAddress clientHost, int clientPort)

  • Socket createSocket (InetAddress host, int port)

  • Socket createSocket (InetAddress host, int port, InetAddress clientHost, int clientPort)

  • Socket createSocket (Socket socket, String host, int port, boolean autoClose)

Podemos usar essa classe diretamente obtendo a instância padrão ou usando um objetojavax.net.ssl.SSLContext que contém métodos para obter uma instânciaSSLSocketFactory.

3.2. SSLSocket

Esta classe estende a classeSocket e fornece soquete seguro. Tais soquetes são soquetes normais de fluxo.

Além disso, eles adicionam uma camada de proteções de segurança ao protocolo de transporte de rede subjacente.

As instânciasSSLSocket constroem uma conexão SSL para um host nomeado em uma porta especificada.

Isso permite vincular o lado do cliente da conexão a um determinado endereço e porta.

3.3. SSLServerSocketFactory

A classeSSLServerSocketFactory é bastante semelhante aSSLSocketFactory, com a diferença de que cria instâncias deSSLServerSocket no lugar de instâncias deSSLSocket.

Por similaridade, os métodos são chamados decreateServerSocket como análogos à classeSSLSocketFactory.

3.4. SSLServerSocket

A classeSSLServerSocket é análoga à classeSSLSocket. Os métodos na classe SSLServerSocket são um subconjunto dos métodos de classeSSLSocket. Eles agem no lado oposto de uma conexão SSL

4. Exemplo de SSL

Vamos fornecer um exemplo de como podemos criar uma conexão segura com um servidor:

String host = getHost(...);
Integer port = getPort(...);
SSLSocketFactory sslsocketfactory = SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory
  .createSocket(host, port);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();

out.write(1);
while (in.available() > 0) {
    System.out.print(in.read());
}

System.out.println("Secured connection performed successfully");

Caso obtenhamos o erro“javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target while establishing the SSL connection”,it indicates that we don’t have the public certificate of the server which we’re trying to connect in the Java truststore.

O armazenamento confiável é o arquivo que contém certificados confiáveis ​​que o Java usa para validar conexões seguras.

Para resolver esse problema, temos várias opções:

  • adicione o certificado público do servidor aocacerts truststore padrão usado pelo Java. enquanto inicia a conexão SSL

  • Defina a variáveljavax.net.ssl.trustStore environment para apontar para o arquivo de armazenamento confiável para que o aplicativo possa selecionar aquele arquivo que contém o certificado público do servidor ao qual estamos nos conectando.

As etapas para instalar um novo certificado no armazenamento confiável padrão do Java são:

  1. extrair certificado do servidor:openssl s_client -connect server:443

  2. importar certificado para armazenamento confiável usando keytool:keytool -import -alias alias.server.com -keystore $JAVA_HOME/jre/lib/security/cacerts

Depois de fazer isso, devemos ser capazes de executar o exemplo novamente e obter a mensagemSecured connection performed successfully.

5. Conclusão

Neste artigo, apresentamos a API SSL e JSSE, que implementa o SSL para Java. Usando SSL e JSSE, podemos tornar nossos aplicativos Java e as comunicações entre aplicativos e dentro dele mais seguros.

Como sempre, o código apresentado neste artigo está disponívelover on Github.