Como proteger algoritmos de criptografia simétrica em Java
18 de outubro de 2023
0 minutos de leituraNo mundo conectado em que vivemos, proteger os dados digitais se tornou uma prioridade. Com a ampla adoção de aplicações Java em diversos setores, do bancário ao de saúde, precisamos destacar a importância da criptografia. Criptografar é transformar dados legíveis, ou texto simples, em dados ilegíveis, ou texto cifrado. Assim, mesmo que os dados criptografados sejam interceptados, pessoas não autorizadas não poderão acessá-los.
A primeira decisão que você precisa tomar como desenvolvedor é se precisa de criptografia. Embora pareça uma pergunta estranha, o princípio fundamental da criptografia é que o texto cifrado pode ser revertido para o texto original. No caso de senhas, por exemplo, não queremos usar criptografia, pois não queremos conseguir “descriptografar” o texto original. Por isso, usamos hashing para senhas, e não criptografia.
Criptografia em Java
As aplicações Java costumam lidar com dados confidenciais, como informações de clientes, dados financeiros e registros de transações. Como desenvolvedor Java, usar algoritmos de criptografia robustos é essencial para manter a integridade e a confidencialidade desses dados. Isso protege seus usuários e todos os dados essenciais armazenados no seu sistema.
Criptografia simétrica e assimétrica
De modo geral, podemos distinguir dois tipos de criptografia: simétrica e assimétrica. Cada tipo funciona de maneira fundamentalmente diferente e atende a casos de uso distintos.
A criptografia simétrica usa a mesma chave para criptografar e descriptografar. Por isso, é mais rápida, mas menos segura quando é necessário compartilhar a chave. Já a criptografia assimétrica usa um par de chaves (pública e privada). A chave pública é usada para criptografar, e a privada, para descriptografar. A criptografia simétrica é indicada para situações em que grandes volumes de dados precisam ser criptografados, enquanto a assimétrica é ideal para compartilhar chaves com segurança pela rede. Embora existam esses dois tipos de criptografia, neste artigo vamos nos concentrar apenas na criptografia simétrica em aplicações Java.
Ao usar criptografia simétrica, o ideal é recorrer a serviços que utilizem módulos de segurança de hardware (HSMs) para gerenciar chaves e padrões de criptografia envelope. Isso simplifica o gerenciamento de chaves, que é a parte mais difícil da solução de criptografia. No entanto, se você não puder usar um serviço como o Amazon Key Management Service (KMS), mas ainda quiser implementar essa abordagem, as informações a seguir mostram como fazer isso com segurança. No restante deste artigo, vamos nos concentrar na implementação de criptografia simétrica na sua aplicação Java usando os pacotes javax.crypto.
Entenda os riscos de algoritmos de criptografia obsoletos
Apesar da importância da criptografia, nem todos os algoritmos são iguais. Alguns algoritmos mais antigos ou “obsoletos”, como DES (Data Encryption Standard) ou 3DES, apresentam vulnerabilidades que podem ser exploradas por invasores. Esses algoritmos já foram considerados seguros, mas os avanços no poder computacional e nas técnicas de criptoanálise os tornaram inseguros.
O uso de algoritmos de criptografia inseguros nas suas aplicações Java pode trazer riscos. Um invasor que consiga acessar seus dados criptografados talvez consiga descriptografá-los se o algoritmo estiver obsoleto e tiver vulnerabilidades conhecidas. Isso pode resultar em uma violação de dados, com consequências potencialmente devastadoras para seus usuários e sua organização.
Recomendações de algoritmos e modos de cifra
Para algoritmos de criptografia simétrica, a fundação OWASP recomenda atualmente o AES (Advanced Encryption Standard) com uma chave de pelo menos 128 bits, de preferência 256 bits. Além disso, você deve usar o algoritmo com um modo seguro. Os padrões e diretrizes de criptografia do NIST também aprovam o AES como uma técnica de cifra de bloco.
Uma cifra como o AES oferece vários modos, cada um com características diferentes de segurança e desempenho. Quanto aos modos, evite o ECB (Electronic Codebook), que não oferece confidencialidade adequada às mensagens. Em vez disso, use modos como CCM (Counter with CBC-MAC) ou GCM (Galois/Counter Mode). Ambos são modos autenticados e garantem a integridade, a confidencialidade e a autenticidade dos dados.
Como identificar algoritmos de criptografia fracos em Java
É relativamente fácil usar as APIs javax.crypto para implementar um pequeno serviço de criptografia em Java. A seguir, veja um exemplo de EncryptionService em Java que usa o algoritmo obsoleto DES com o modo ECB.
Agora que adicionamos a um projeto um algoritmo de criptografia conhecido por ser inseguro, vamos usar o serviço gratuito da Snyk para detectar esse uso inseguro e encontrar uma solução melhor.
Primeiro, crie uma conta gratuita na Snyk. Você pode começar facilmente usando sua conta do GitHub, Bitbucket, Azure AD ou Docker.
Em seguida, conectei meu repositório do GitHub à Snyk. A análise estática do Snyk Code me alerta imediatamente que minha aplicação usa um algoritmo criptográfico vulnerável ou arriscado. O alerta está correto, pois há várias referências a DES no serviço acima. O mecanismo do Snyk Code também recomenda considerar o uso do AES, de acordo com as orientações da OWASP.

Embora use AES no breve trecho de código abaixo, estou usando o modo CBC, que não é considerado seguro.
A Snyk também identifica o uso de modos inseguros, entre outros problemas. A captura de tela abaixo foi feita no plugin da Snyk, que analisa meu código no IntelliJ IDEA e fornece informações úteis, como exemplos de correções externas.

Alterar o EncryptionService para uma versão que use AES/GCM/NoPadding, como a seguir, é uma solução muito melhor do que a anterior e está de acordo com as recomendações atuais da OWASP.
Revise continuamente os algoritmos de criptografia nas suas aplicações Java
Atualizar algoritmos de criptografia obsoletos é essencial, mas também é importante monitorar continuamente sua base de código em busca de novos problemas de segurança. Os algoritmos considerados seguros no momento em que este artigo foi escrito certamente estarão obsoletos em alguns anos.
Por isso, a análise proativa para identificar esses problemas deve ser contínua. Isso vale não apenas para algoritmos de criptografia, mas também para outros problemas no código que você mantém. Adotar e usar uma ferramenta de teste de segurança por análise estática (SAST), como o Snyk Code, ajuda você a reconhecer, identificar e corrigir esses problemas com facilidade, antes que causem danos.
Use o Snyk Code para Java gratuitamente
O Snyk Code é uma ferramenta de ponta para testes de segurança de aplicações estáticas (SAST) que identifica vulnerabilidades de segurança na sua base de código. Ele oferece suporte a várias linguagens de programação, incluindo Java, analisando o código e fornecendo feedback em tempo real aos desenvolvedores. Você pode integrar o Snyk Code ao seu pipeline de CI/CD para analisar o código automaticamente a cada commit e identificar e corrigir problemas de segurança logo no início do ciclo de desenvolvimento. Além disso, você pode conectá-lo ao seu repositório Git, usá-lo pela linha de comando com nossa CLI e integrá-lo a todas as principais IDEs para Java.
Assim, você identifica problemas no código desde cedo e em todas as etapas do ciclo de desenvolvimento. E o melhor: você pode usar a ferramenta gratuitamente. Basta se inscrever na Snyk abaixo.
Comece a jogar Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo à gravação sob demanda do nosso workshop virtual introdutório.
Os exemplos de código deste post estão publicados no GitHub para você testar por conta própria. Se quiser conferir mais recursos sobre segurança para desenvolvedores Java, veja:



