Criptografía en Kotlin: cifrado y hash

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Criptografía en Kotlin: cifrado y hashing

Kotlin, ejecutándose sobre la JVM, proporciona acceso completo a las potentes bibliotecas criptográficas de Java, como Java Cryptography Extension (JCE) y Bouncy Castle. En este artículo, veremos cómo implementar cifrado simétrico (AES), asimétrico (RSA) y hashing (SHA-256) en Kotlin. Todos los ejemplos de código están listos para ejecutarse: puedes copiarlos en tu proyecto.



Preparación del proyecto

Para empezar, añade la dependencia de Bouncy Castle (proveedor recomendado para algoritmos modernos) en tu build.gradle.kts:

dependencies {    implementation("org.bouncycastle:bcprov-jdk15on:1.70")}

Después de sincronizar Gradle, importa el proveedor en el código:

import org.bouncycastle.jce.provider.BouncyCastleProviderimport java.security.Security

fun initCrypto() { Security.addProvider(BouncyCastleProvider())}


1. Hashing SHA-256

El hashing es una transformación irreversible de datos. Se usa más comúnmente para verificar la integridad de archivos y almacenar contraseñas.

import java.security.MessageDigest

fun sha256(input: String): String { val digest = MessageDigest.getInstance("SHA-256") val hashBytes = digest.digest(input.toByteArray()) return hashBytes.joinToString("") { "%02x".format(it) }}

fun main() { val password = "mySecret123" val hash = sha256(password) println("SHA-256 hash: $hash") // Salida: SHA-256 hash: a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3}

Importante: Para contraseñas, usa bcrypt o scrypt — SHA-256 es demasiado rápido y vulnerable a ataques de fuerza bruta.



2. Cifrado simétrico AES

AES (Advanced Encryption Standard) es el algoritmo más popular para cifrar datos. Usamos el modo GCM (garantiza autenticidad) y un IV aleatorio.

import javax.crypto.Cipherimport javax.crypto.KeyGeneratorimport javax.crypto.SecretKeyimport javax.crypto.spec.GCMParameterSpecimport java.util.Base64

class AesGcmEncryption { companion object { private const val AES_KEY_SIZE = 256 private const val GCM_IV_LENGTH = 12 private const val GCM_TAG_LENGTH = 128 }

fun generateKey(): SecretKey { val keyGen = KeyGenerator.getInstance("AES") keyGen.init(AES_KEY_SIZE) return keyGen.generateKey() }

fun encrypt(plainText: String, secretKey: SecretKey): String { val cipher = Cipher.getInstance("AES/GCM/NoPadding") val iv = ByteArray(GCM_IV_LENGTH).apply { java.security.SecureRandom().nextBytes(this) } cipher.init(Cipher.ENCRYPT_MODE, secretKey, GCMParameterSpec(GCM_TAG_LENGTH, iv)) val cipherText = cipher.doFinal(plainText.toByteArray()) // Combinamos IV y texto cifrado val combined = iv + cipherText return Base64.getEncoder().encodeToString(combined) }

fun decrypt(encryptedData: String, secretKey: SecretKey): String { val combined = Base64.getDecoder().decode(encryptedData) val iv = combined.copyOfRange(0, GCM_IV_LENGTH) val cipherText = combined.copyOfRange(GCM_IV_LENGTH, combined.size) val cipher = Cipher.getInstance("AES/GCM/NoPadding") cipher.init(Cipher.DECRYPT_MODE, secretKey, GCMParameterSpec(GCM_TAG_LENGTH, iv)) return String(cipher.doFinal(cipherText)) }}

fun main() { val aes = AesGcmEncryption() val key = aes.generateKey() val original = "Mensaje secreto" val encrypted = aes.encrypt(original, key) val decrypted = aes.decrypt(encrypted, key) println("Original: $original") println("Cifrado: $encrypted") println("Descifrado: $decrypted")}


3. Asimétri

Recommendations