Криптография в Kotlin: шифрование и хеширование
Kotlin, работающий поверх JVM, предоставляет полный доступ к мощным криптографическим библиотекам Java, таким как Java Cryptography Extension (JCE) и Bouncy Castle. В этой статье мы рассмотрим, как реализовать симметричное (AES), асимметричное (RSA) шифрование, а также хеширование (SHA-256) на Kotlin. Все примеры кода готовы к запуску — вы можете скопировать их в свой проект.
Подготовка проекта
Для начала добавьте в build.gradle.kts зависимость от Bouncy Castle (рекомендуемый провайдер для современных алгоритмов):
dependencies {
implementation("org.bouncycastle:bcprov-jdk15on:1.70")
}
После синхронизации Gradle импортируйте провайдер в коде:
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.security.Security
fun initCrypto() {
Security.addProvider(BouncyCastleProvider())
}
1. Хеширование SHA-256
Хеширование — это необратимое преобразование данных. Чаще всего используется для проверки целостности файлов и хранения паролей.
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")
// Вывод: SHA-256 хеш: a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
}
Важно: Для паролей используйте bcrypt или scrypt — SHA-256 слишком быстрый и уязвим к атакам перебором.
2. Симметричное шифрование AES
AES (Advanced Encryption Standard) — самый популярный алгоритм для шифрования данных. Используем режим GCM (гарантирует аутентичность) и случайный IV.
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.GCMParameterSpec
import 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())
// Объединяем IV и шифротекст
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 = "Секретное сообщение"
val encrypted = aes.encrypt(original, key)
val decrypted = aes.decrypt(encrypted, key)
println("Оригинал: $original")
println("Зашифровано: $encrypted")
println("Расшифровано: $decrypted")
}
3. Асимметричное шифрование RSA
RSA использует пару ключей: открытый (для шифрования) и закрытый (для расшифровки). Идеально подходит для передачи симметричных ключей.
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import javax.crypto.Cipher
import java.util.Base64
class RsaEncryption {
fun generateKeyPair(): Pair<PublicKey, PrivateKey> {
val generator = KeyPairGenerator.getInstance("RSA")
generator.initialize(2048) // 2048 бит — безопасный минимум
val keyPair = generator.generateKeyPair()
return Pair(keyPair.public, keyPair.private)
}
fun encrypt(plainText: String, publicKey: Public Также в библиотеке
Планировщик задач Java: Quartz Scheduler — полное руководство
Обработка изображений в Node.js: resize, crop с Sharp и Jimp
Elasticsearch клиент для TypeScript: @elastic/elasticsearch
Retrofit для Kotlin: полное руководство с примерами
GraphQL библиотека TypeScript: полное руководство по инструментам