Criptografía en Kotlin: cifrado y hashing
El desarrollo moderno en Kotlin (especialmente para Android y backend) a menudo requiere la implementación de funciones criptográficas. En este artículo, exploraremos los enfoques principales para el cifrado y hashing de datos utilizando Kotlin y las bibliotecas estándar Java Cryptography Extension (JCE) y Bouncy Castle.
Conceptos básicos
La criptografía en Kotlin se basa en las capacidades de la JVM. Puedes usar:
- Cifrado simétrico (AES, DES) — una clave para cifrar y descifrar.
- Cifrado asimétrico (RSA) — un par de claves: pública y privada.
- Hashing (SHA-256, MD5) — transformación irreversible de datos.
- HMAC — hashing con clave secreta para verificar la integridad.
Configuración del proyecto
Para la mayoría de los ejemplos, la biblioteca estándar de Java es suficiente. Para algoritmos avanzados (por ejemplo, AES con GCM), agrega la dependencia en build.gradle.kts:
dependencies { implementation("org.bouncycastle:bcprov-jdk15on:1.70")}1. Cifrado simétrico (AES)
AES es el algoritmo más popular. Ejemplo de cifrado y descifrado de una cadena:
import javax.crypto.Cipherimport javax.crypto.KeyGeneratorimport javax.crypto.SecretKeyimport javax.crypto.spec.IvParameterSpecimport java.util.Base64
fun aesEncrypt(plainText: String, secretKey: SecretKey): String { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val iv = ByteArray(16) // Generación de IV java.security.SecureRandom().nextBytes(iv) cipher.init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(iv)) val encrypted = cipher.doFinal(plainText.toByteArray()) // Combinamos IV y texto cifrado val combined = iv + encrypted return Base64.getEncoder().encodeToString(combined)}
fun aesDecrypt(encryptedBase64: String, secretKey: SecretKey): String { val combined = Base64.getDecoder().decode(encryptedBase64) val iv = combined.copyOfRange(0, 16) val encrypted = combined.copyOfRange(16, combined.size) val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(iv)) return String(cipher.doFinal(encrypted))}
// Usofun main() { val keyGen = KeyGenerator.getInstance("AES") keyGen.init(256) val secretKey = keyGen.generateKey()
val original = "¡Hola, Kotlin Crypto!" val encrypted = aesEncrypt(original, secretKey) println("Cifrado: $encrypted")
val decrypted = aesDecrypt(encrypted, secretKey) println("Descifrado: $decrypted")}2. Cifrado asimétrico (RSA)
RSA se utiliza para la transmisión segura de datos. Ejemplo:
import java.security.KeyPairGeneratorimport java.security.PrivateKeyimport java.security.PublicKeyimport javax.crypto.Cipherimport java.util.Base64
fun generateRSAKeyPair(): Pair<PublicKey, PrivateKey> { val generator = KeyPairGenerator.getInstance("RSA") generator.initialize(2048) val keyPair = generator.generateKeyPair() return Pair(keyPair.public, keyPair.private)}
fun rsaEncrypt(plainText: String, publicKey: PublicKey): String { val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") cipher.init(Cipher.ENCRYPT_MODE, publicKey) return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.toByteArray()))}
fun rsaDecrypt(encryptedBase64: String, privateKey: PrivateKey): String { val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") cipher.init(Cipher.DECRYPT_MODE, privateKey) return String(cipher.doFinal(Base64.getDecoder().decode(encryptedBase64)))}
fun main() { val (publicKey, privateKey) = generateRSAKeyPair() val message = "Mensaje secreto" val encryp También en la biblioteca
Migraciones de bases de datos en Java: revisión de herramientas y bibliotecas
Clap para Rust: guía completa con ejemplos