Por que char[] é melhor que String para senhas? Guia com código

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que esta questão ainda é relevante?



Imagine a situação: você está escrevendo um aplicativo para login. O usuário digita uma senha e você precisa verificá-la. Parece que o mais simples é armazená-la como uma string (String). Mas desenvolvedores Java experientes dirão: "Nunca use String para senhas! Use char[]!". Por quê?



Esta questão é uma das mais populares no Stack Overflow (mais de 100.000 visualizações). E não é que String não saiba armazenar caracteres. O problema é mais profundo: diz respeito à segurança, gerenciamento de memória e vazamento de dados. Neste artigo, vamos analisar por que char[] para senha é o padrão de segurança e mostrar com exemplos de código como implementar corretamente essa prática em Java.



Se você está começando a aprender Java ou quer aumentar o nível de segurança dos seus aplicativos, este artigo é para você.



Problema nº 1: Imutabilidade de String



A classe String em Java é imutável (immutable). Isso significa que, após criar um objeto String, seu valor não pode ser alterado. Qualquer operação que "mude" a string (por exemplo, toUpperCase() ou replace()) na verdade cria um novo objeto String na memória.



Por que isso é ruim para senhas? Vamos ver um exemplo:



String password = "MySecret123";// ... usamos a senha para verificação ...// Terminamos de trabalhar com a senhapassword = null; // "limpamos" a referência


Você acha que limpou a memória? Não! O objeto "MySecret123" ainda está na memória, no chamado String Pool (pool de strings). O coletor de lixo (GC) não o removerá imediatamente. Ele ficará armazenado lá até a próxima coleta de lixo, ou melhor, até que não haja mais referências a ele. E mesmo após password = null, o próprio objeto pode permanecer na memória por um tempo indeterminado.



E se um invasor obtiver um dump de memória (heap dump) do seu aplicativo? Ele poderá ler a senha em texto claro. A imutabilidade de String torna impossível a remoção imediata da senha da memória.



Problema nº 2: String Pool e vazamento de senhas



O Java otimiza o trabalho com strings através do String Pool. Quando você cria uma string usando um literal (por exemplo, "password"), ela é colocada no pool. Se outra parte do programa usar a mesma string, ela simplesmente referencia o objeto existente.



Agora imagine que sua senha seja "admin123". Essa mesma senha pode ser acidentalmente usada em outro lugar no sistema (por exemplo, em logs, em um nome de arquivo ou em uma configuração). A string "admin123" vive no pool para sempre (pelo menos até o término da JVM). Isso aumenta a superfície de ataque.



// Código que pode causar vazamentoString password = "admin123";System.out.println("Senha: " + password); // A senha vai para os logs// Mesmo que depois password = null, a string "admin123" permaneceu nos logs e no pool


Com o array char[] não há esse problema: você pode sobrescrever explicitamente cada elemento do array após o uso.



Solução: array char[] e gerenciamento manual de memória



O array de caracteres char[] é um objeto mutável. Você pode alterar seu conteúdo a qualquer momento. A principal vantagem: você pode limpar o array imediatamente após a senha não ser mais necessária.



Veja como fica na prática:



import java.util.Arrays;

public class PasswordExample { public static void main(String[] args) { // Incorreto: String String passwordString = "MySecret123"; // ... verificação ... passwordString = null; // A senha ainda pode estar na memória // Correto: char[] char[] passwordChars = { 'M', 'y', 'S', 'e', 'c', 'r', 'e',

Blogs

Book Recommendations