Autenticação segura em Kotlin: guia para desenvolvedores

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 a autenticação "feita em casa" é um risco?

\n\n

Imagine: você está escrevendo um aplicativo em Kotlin — seja um cliente Android ou um backend em Ktor/Spring Boot. Você rapidamente cria um formulário de login, salva a senha em SharedPreferences e fica feliz que tudo funciona. E uma semana depois, recebe uma mensagem: "Seu aplicativo foi hackeado, dados vazaram". Familiar? Infelizmente, isso é clássico.

\n\n

Autenticação segura em Kotlin não é apenas "verificar a senha". É todo um ecossistema: hash, tokens, proteção contra falsificação de solicitações, armazenamento seguro de segredos. Neste artigo, vamos abordar como evitar erros típicos e construir um sistema de login robusto. Vamos lá!

\n\n

1. Hash de senhas: bcrypt e seus amigos

\n\n

A primeira regra de segurança: nunca armazene senhas em texto puro. Mesmo que você use HTTPS, o banco de dados pode ser comprometido. Sua tarefa é armazenar apenas o hash.

\n\n

Por que MD5 e SHA são ruins?

\n

Esses algoritmos são rápidos. E hashes rápidos são o sonho de um invasor: ele pode testar bilhões de combinações por segundo. Em vez deles, use bcrypt, scrypt ou Argon2. Eles são intencionalmente lentos e resistentes a ataques de GPU.

\n\n

Exemplo em Kotlin usando a biblioteca jbcrypt:

\n\n
import org.mindrot.jbcrypt.BCrypt\n\nfun hashPassword(password: String): String {\n    val salt = BCrypt.gensalt(12) // fator de custo 12 — ideal\n    return BCrypt.hashpw(password, salt)\n}\n\nfun checkPassword(password: String, hashed: String): Boolean {\n    return BCrypt.checkpw(password, hashed)\n}
\n\n

Importante: o salt é gerado automaticamente e incorporado ao hash. Você não precisa armazená-lo separadamente.

\n\n

2. JWT: autenticação leve e segura

\n\n

JSON Web Token (JWT) é um padrão para transmitir afirmações (claims) entre partes. Em Kotlin, você pode usar a biblioteca java-jwt (Auth0) ou jsonwebtoken (jjwt).

\n\n

Geração de JWT em Kotlin

\n\n
import io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.SignatureAlgorithm\nimport io.jsonwebtoken.security.Keys\nimport java.util.Date\n\nfun generateToken(userId: String, secretKey: String): String {\n    val key = Keys.hmacShaKeyFor(secretKey.toByteArray())\n    return Jwts.builder()\n        .setSubject(userId)\n        .setIssuedAt(Date())\n        .setExpiration(Date(System.currentTimeMillis() + 3600_000)) // 1 hora\n        .signWith(key, SignatureAlgorithm.HS256)\n        .compact()\n}
\n\n

Validação do token

\n\n
fun validateToken(token: String, secretKey: String): String? {\n    return try {\n        val key = Keys.hmacShaKeyFor(secretKey.toByteArray())\n        val claims = Jwts.parserBuilder()\n            .setSigningKey(key)\n            .build()\n            .parseClaimsJws(token)\n            .body\n        claims.subject // retorna o userId\n    } catch (e: Exception) {\n        null // token inválido ou expirado\n    }\n}
\n\n

Dica: não armazene a chave secreta no código. Use variáveis de ambiente ou Vault.

\n\n

3. Armazenamento seguro de tokens no Android

\n\n

Se você está escrevendo um aplicativo móvel em Kotlin, o token de acesso não pode ser armazenado em SharedPreferences — é um arquivo aberto que pode ser lido por outros aplicativos ou por um invasor com acesso root.

\n\n

Use EncryptedSharedPreferences (do AndroidX Security) ou Keystore:

\n\n
import androidx.security.crypto.EncryptedSharedPreferences\nimport androidx.security.crypto.MasterKey\n\nfun saveToken(context: Context, token: String) {\n    val masterKey = MasterKey.Builder(context)\n        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)\n        .build()\n\n    val sharedPreferences = EncryptedSharedPreferences.create(\n        context,\n        "secure_prefs",\n        masterKey,\n                

Blogs

Book Recommendations