Криптография в Kotlin: шифрование и хеширование
Kotlin, будучи современным языком для JVM, предоставляет доступ ко всем мощностям Java Cryptography Architecture (JCA). Это позволяет реализовывать как симметричное (AES, DES), так и асимметричное (RSA) шифрование, а также криптографические хеш-функции (SHA-256, MD5) и цифровые подписи. В этой статье мы разберем практические примеры использования криптографии в Kotlin, которые пригодятся для защиты данных в веб-приложениях, мобильных разработках и бэкенд-сервисах.
Все примеры кода используют встроенные возможности Java, что делает их кроссплатформенными и не требующими дополнительных библиотек.
1. Симметричное шифрование AES в Kotlin
Симметричное шифрование использует один и тот же ключ для шифрования и расшифровки. Алгоритм AES (Advanced Encryption Standard) является золотым стандартом безопасности. Рассмотрим пример шифрования строки с использованием режима CBC и PKCS5Padding.
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.util.Base64
fun generateAESKey(): SecretKey {
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(256) // Длина ключа: 128, 192 или 256 бит
return keyGen.generateKey()
}
fun encryptAES(plainText: String, secretKey: SecretKey, iv: ByteArray): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec)
val encrypted = cipher.doFinal(plainText.toByteArray())
return Base64.getEncoder().encodeToString(encrypted)
}
fun decryptAES(encryptedText: String, secretKey: SecretKey, iv: ByteArray): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec)
val decoded = Base64.getDecoder().decode(encryptedText)
val decrypted = cipher.doFinal(decoded)
return String(decrypted)
}
fun main() {
val key = generateAESKey()
val iv = ByteArray(16) // Инициализационный вектор (16 байт для AES)
// В реальном проекте iv должен быть случайным и передаваться вместе с шифротекстом
val original = "Привет, Kotlin!"
val encrypted = encryptAES(original, key, iv)
val decrypted = decryptAES(encrypted, key, iv)
println("Оригинал: $original")
println("Зашифровано: $encrypted")
println("Расшифровано: $decrypted")
}
Важно: Инициализационный вектор (IV) должен быть случайным для каждого шифрования и передаваться открыто вместе с зашифрованными данными. Никогда не используйте фиксированный IV в продакшене.
2. Асимметричное шифрование RSA в Kotlin
RSA использует пару ключей: открытый (public) для шифрования и закрытый (private) для расшифровки. Это идеально для безопасной передачи данных между сторонами.
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import javax.crypto.Cipher
import java.util.Base64
fun generateRSAKeyPair(): Pair<PublicKey, PrivateKey> {
val keyGen = KeyPairGenerator.getInstance("RSA")
keyGen.initialize(2048) // Рекомендуемый размер ключа
val keyPair = keyGen.generateKeyPair()
return Pair(keyPair.public, keyPair.private)
}
fun encryptRSA(plainText: String, publicKey: PublicKey): String {
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val encrypted = cipher.doFinal(plainText.toByteArray())
return Base64.getEncoder().encodeToString(encrypted)
}
fun decryptRSA(encryptedText: String, privateKey: PrivateKey): String {
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val decoded = Base64.getDecoder().decode(encryptedText)
val decrypted = cipher.doFinal(decoded)
return String(decrypted)
}
fun main() {
val (publicKey, privateKey) = generateRSAKeyPair()
val message = "Секретное сообщение"
val encrypted = encryptRSA(message, publicKey)
val decrypted = decryptRSA(encrypted, privateKey)
println("Исходное: $message")
println("Зашифровано: $encrypted")
println("Расшифровано: $decrypted")
}
RSA медленнее AES, поэтому на практике его используют для шифрования симметричных ключей (гибридная схема) или малых объемов данных.
3. Хеширование SHA-256 в Kotlin
Хеширование — это необратимое преобраз