Autenticação segura em Java: como não reprovar no exame de segurança

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 sua senha não é apenas uma string

\n\n

Imagine: você escreveu uma aplicação Java incrível para uma biblioteca online. Os usuários se registram, salvam favoritos, escrevem resenhas. E de repente — um vazamento de banco de dados. Todas as senhas em texto puro. Catástrofe? Com certeza! Em 2024, vazamentos de dados ocorrem a cada 39 segundos, e 81% deles estão relacionados à autenticação fraca. Se você programa em Java e quer que seu projeto não apareça nos noticiários de cibersegurança — este artigo é para você.

\n\n

Vamos abordar a autenticação segura em aplicações Java do início ao fim: desde hash de senhas até JWT e proteção contra CSRF. Sem teoria entediante, apenas código funcional e práticas reais. Vamos lá!

\n\n

1. Hash de senhas: primeira linha de defesa

\n\n

A primeira regra de segurança: nunca armazene senhas em texto puro. Mesmo que seu banco de dados seja o cálice sagrado, a criptografia de senhas é o mínimo obrigatório. Em Java, usam-se algoritmos como bcrypt, scrypt ou Argon2. Por que não MD5 ou SHA? Porque são muito rápidos — um invasor descobriria a senha em segundos.

\n\n

Prática: bcrypt em ação

\n

Adicione a dependência no pom.xml (Maven):

\n
<dependency>\n    <groupId>org.springframework.security</groupId>\n    <artifactId>spring-security-crypto</artifactId>\n    <version>6.2.0</version>\n</dependency>\n
\n\n

Agora, faça o hash da senha no registro:

\n
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\n\npublic class PasswordService {\n    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();\n\n    public String hashPassword(String rawPassword) {\n        return encoder.encode(rawPassword); // gera salt automaticamente\n    }\n\n    public boolean checkPassword(String rawPassword, String storedHash) {\n        return encoder.matches(rawPassword, storedHash);\n    }\n}\n
\n\n

Importante: o bcrypt adiciona um salt aleatório automaticamente, então mesmo senhas iguais terão aparências diferentes. O custo (cost factor) padrão é 10, mas para sistemas críticos pode ser aumentado para 12-14.

\n\n

2. JWT (JSON Web Tokens): sessão leve e segura

\n\n

Após o registro, o usuário precisa confirmar sua identidade de alguma forma. Cookies? Pode ser, mas JWT é o padrão moderno para APIs REST. O token contém informações do usuário e é assinado com uma chave secreta. Sem sessões no servidor — tudo está no token.

\n\n

Criação de JWT em Java

\n

Adicione a biblioteca io.jsonwebtoken:jjwt:

\n
<dependency>\n    <groupId>io.jsonwebtoken</groupId>\n    <artifactId>jjwt-api</artifactId>\n    <version>0.12.3</version>\n</dependency>\n
\n\n

Geração do token:

\n
import io.jsonwebtoken.Jwts;\nimport io.jsonwebtoken.security.Keys;\nimport javax.crypto.SecretKey;\nimport java.util.Date;\n\npublic class JwtUtil {\n    private final SecretKey key = Keys.hmacShaKeyFor("chave_secreta_com_pelo_menos_256_bits".getBytes());\n\n    public String generateToken(String username) {\n        return Jwts.builder()\n                .subject(username)\n                .issuedAt(new Date())\n                .expiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hora\n                .signWith(key)\n                .compact();\n    }\n\n    public String extractUsername(String token) {\n        return Jwts.parser()\n                .verifyWith(key)\n                .build()\n                .parseSignedClaims(token)\n                .getPayload()\n                .getSubject();\n    }\n}\n
\n\n

Dica: não armazene a chave secreta no código! Use variáveis de ambiente ou Vault. E nunca coloque dados confidenciais (senhas, números de cartão) no JWT — o token pode ser decodificado sem a assinatura.

\n\n

3. Proteção contra CSRF:

Blogs

Book Recommendations