Tuesday, January 28, 2020

Criptografia e Segurança com Java: parte 1


Criptografia é a prática e o estudo de técnicas que viabilizam uma comunicação segura entre duas partes, através de um canal inseguro (a internet, por exemplo) de modo que seja assegurada a total confidencialidade da mensagem trocada entre as partes, isto é, se algum terceiro interceptar a mensagem, ele não terá condições de entender seu conteúdo, porque a mesma estará criptografada. Caso ele consiga decifrar a mensagem, diz-se que a criptografia foi quebrada.


Em resumo, seguindo a ilustração acima, extraida do livro Understanding Cryptography de Christof Paar e Jan Pelzl, Oscar é um sujeito mau que tentará interceptar a mensagem trocada entre Alice e Bob. Quando se trata de criptografia, temos duas funções:

e(): criptografa (encrypt) o texto x usando a chave k e retorna y (y é x criptografado)

d(): descriptografa (decrypty usando a mesma chave k, de modo que o resultado seja o texto x original

Quando a chave que criptografa e descriptografa são iguais, diz-se que a cripografia é simétrica; quando são diferentes, a criptografia é asimetrica.

Existem dezenas de algoritimos que determinam as etapas para criptografar/descriptografar o texto usando uma determinada chave. Exemplos comuns:

DES: (Data Encryption Standard) durante quase 3 décadas foi o método mais popular de criptografia simétrica. Caiu em desuso no final dos anos 90, quando o barateamento do poder computacional viabilizou a quebra desse método.

RSA: (Rivest–Shamir–Adleman) este algoritmo usa chave asimétrcia, o que significa que a chave que criptografa é diferente da chave que descriptografa. Considerado seguro, é muito usado em autenticações SSH e SSL.

AES: (Advanced Encryption Standard) Largamente aceito hoje, substituiu o DES, tambem é simétrico. AES é o padrão pelo NIST. É usando principalmente em comunicações via HTTPS.

SHA: (Secure Hash Algorithm) Representa uma família de algoritmos (SHA-0, SHA-1, SHA-2, etc.). Transforma o texto usando uma função hash. A criptografia usando SHA só tem um-caminho, ou seja, uma vez criptografada a mensagem, é impossível recuperar a mensagem de volta a partir do hash. Uma aplicação comum do SHA é criptografia de senhas e assinaturas digitais.

MD5: (Message Digest 5) Assim como o SHA, o MD5 é uma função hash de mão única.

A relação completa dos algoritmos suportados pela plataforma Java está na documentação da arquitetura de criptografia do Java.

Exemplo de DES (Data Encryption Standard) em Java

Neste exemplo em java criptografamos uma mensagem utilzando o algoritmo DES, e depois descriptografamos de volta para a original. As classes e interfaces que provem operações de criptografia no java estão no pacote javax.cripto. O pacote java.security também dá suporte para essas operações (as declarações de import estão omitidas).

/**
 * DES (Data Encryption Standard)
 */
public class _01_DES_example {

    //javax.crypto.Cipher provê funcionalidade para Criptografar ou Descriptografar.
    private static Cipher eCipher;
    private static Cipher dCipher;

    // java.security.Key é a interface que representa todos tipos de chave em java
    private static Key secretKey;

    public static void main(String args[])
    {
        try
        {
            // gera uma chave secreta para o algoritmo especificado 'DES'
            secretKey = KeyGenerator.getInstance("DES").generateKey();

            // cria uma instansia de Cipher que irá implementar a transformação da mensagem de acordo com
            // algoritmo especificado, neste caso DES
            eCipher = Cipher.getInstance("DES");
            dCipher = Cipher.getInstance("DES");

            // inicializa este cipher, especificando que ele irá criptografar mensagens
            eCipher.init(Cipher.ENCRYPT_MODE, secretKey);

            // inicializa este cipher, especificando que ele irá DEScriptografar mensagens
            dCipher.init(Cipher.DECRYPT_MODE, secretKey);

            // como a chave que faz a criptografia e a descriptografia é a mesma, então a operação é simétrica

            // mensagem a ser criptografada
            String classifiedMessage = new String("Top secret - This is a classified message!");

            // metodo auxiliar
            String encryptedMsg = criptografar(classifiedMessage);
            System.out.println("\nmenssagem criptografada: "+encryptedMsg);

            // metodo auxiliar
            String decrypted = descriptografar(encryptedMsg);
            System.out.println("\nmensagem descriptografada: "+decrypted);
        }
        // exceções checadas durante o processo de des/criptografia
        catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e)
        {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
    }

    static String criptografar(String classifiedMessage) throws UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException {
        // converte a String em bytes
        byte[] utf8 = classifiedMessage.getBytes("UTF-8");

        // criptografa a mensagem
        byte[] mensagemCriptografada = eCipher.doFinal(utf8);

        // converte em base64 para transmissao na rede
        mensagemCriptografada = Base64.getEncoder().encode(mensagemCriptografada);

        return new String(mensagemCriptografada);
    }

    // faz o caminho inverso do metodo criptografar()
    static String descriptografar(String encryptedMessage) throws BadPaddingException, IllegalBlockSizeException {

        // volta para base decimal
        byte[] dec = Base64.getDecoder().decode(encryptedMessage);

        // descriptografa a mensagem
        byte[] utf8 = dCipher.doFinal(dec);

        // retorna a mensagem original
        return new String(utf8);
    }
}

A conversão do texto criptografado em Base64 é necessária para garantir que todos os caracteres da mensagem cheguem integralmente ao destino, uma vez que, sem esse tratamento, durante o tráfego nas diferentes camadas da rede, alguns protocolos ou equipamentos poderiam interpretar errôneamente alguns caracteres e corromper a mensagem.

Resultado da execução do exemplo:

menssagem criptografada: +dIABfsau+f6eq021nwy/dN3ohqDFNcW7Gy6Yfs2PRFV6Fm+vLUc78QTlW8W4m3S

mensagem descriptografada: Top secret - This is a classified message!


"Estejam sempre alegres, rezem sem cessar. Dêem graças em todas as circunstâncias, porque esta é a vontade de Deus a respeito de vocês em Jesus Cristo. Não extingam o Espírito, não desprezem as profecias; examinem tudo e fiquem com o que é bom. Fiquem longe de toda espécie de mal."

1 Ts 5:16-22

s        

No comments:

Post a Comment