🎯 Рекомендуемые коллекции
Балансированные коллекции примеров кода из различных категорий, которые вы можете исследовать
Примеры Криптографии Android Kotlin
Примеры криптографии Android Kotlin включая вычисление хеша, AES-шифрование и кодирование Base64
💻 Кодирование Base64 kotlin
🟢 simple
⭐⭐
Кодировать и декодировать данные, используя Base64 с различными опциями и наборами символов
⏱️ 20 min
🏷️ kotlin, android, base64, encoding
Prerequisites:
Basic Kotlin
// Android Kotlin Base64 Encoding Examples
// Using java.util.Base64 (Android API 26+) and android.util.Base64
import java.util.Base64
import android.util.Base64 as AndroidBase64
import java.nio.charset.StandardCharsets
// 1. Basic Base64 Encoding/Decoding
class BasicBase64 {
// Encode string to Base64
fun encodeToString(input: String): String {
val encodedBytes = Base64.getEncoder().encode(input.toByteArray())
return String(encodedBytes)
}
// Decode Base64 to string
fun decodeString(encoded: String): String {
val decodedBytes = Base64.getDecoder().decode(encoded)
return String(decodedBytes)
}
// Encode bytes to Base64
fun encodeBytes(bytes: ByteArray): String {
return Base64.getEncoder().encodeToString(bytes)
}
// Decode Base64 to bytes
fun decodeToBytes(encoded: String): ByteArray {
return Base64.getDecoder().decode(encoded)
}
// Encode with URL-safe mode
fun encodeUrlSafe(input: String): String {
return Base64.getUrlEncoder().encodeToString(input.toByteArray())
}
// Decode URL-safe Base64
fun decodeUrlSafe(encoded: String): String {
val decodedBytes = Base64.getUrlDecoder().decode(encoded)
return String(decodedBytes)
}
}
// 2. Android Base64 (Compat for older API levels)
class AndroidBase64Codec {
// Encode using Android Base64
fun encode(input: String, flags: Int = AndroidBase64.NO_WRAP): String {
val inputBytes = input.toByteArray(StandardCharsets.UTF_8)
val encoded = AndroidBase64.encode(inputBytes, flags)
return String(encoded)
}
// Decode using Android Base64
fun decode(encoded: String, flags: Int = AndroidBase64.NO_WRAP): String {
val decoded = AndroidBase64.decode(encoded, flags)
return String(decoded, StandardCharsets.UTF_8)
}
// Encode with NO_WRAP (no padding)
fun encodeNoWrap(input: String): String {
return encode(input, AndroidBase64.NO_WRAP)
}
// Encode with CRLF (line breaks)
fun encodeWithCRLF(input: String): String {
return encode(input, AndroidBase64.CRLF)
}
}
// 3. Base64 for Binary Data
class BinaryBase64 {
// Encode image to Base64
fun encodeImage(imageBytes: ByteArray): String {
return Base64.getEncoder().encodeToString(imageBytes)
}
// Decode Base64 to image bytes
fun decodeToImage(encoded: String): ByteArray {
return Base64.getDecoder().decode(encoded)
}
// Encode file to Base64
fun encodeFile(file: java.io.File): String {
val bytes = file.readBytes()
return Base64.getEncoder().encodeToString(bytes)
}
// Decode Base64 and save to file
fun decodeToFile(encoded: String, file: java.io.File): Boolean {
return try {
val bytes = Base64.getDecoder().decode(encoded)
file.writeBytes(bytes)
true
} catch (e: Exception) {
println("Error decoding to file: ${e.message}")
false
}
}
// Encode with MIME encoding (76 chars per line)
fun encodeMime(input: String): String {
return Base64.getMimeEncoder().encodeToString(input.toByteArray())
}
// Decode MIME encoding
fun decodeMime(encoded: String): String {
val decodedBytes = Base64.getMimeDecoder().decode(encoded)
return String(decodedBytes)
}
}
// 4. Base64 Streams
class Base64Streams {
// Encode large file with streaming
fun encodeLargeFile(inputFile: java.io.File, outputFile: java.io.File): Boolean {
return try {
java.io.FileInputStream(inputFile).use { inputStream ->
java.io.FileOutputStream(outputFile).use { outputStream ->
val encoder = Base64.getEncoder().wrap(outputStream)
val buffer = ByteArray(4096)
var bytesRead: Int
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
encoder.write(buffer, 0, bytesRead)
}
encoder.close()
}
}
true
} catch (e: Exception) {
println("Error encoding large file: ${e.message}")
false
}
}
// Decode large file with streaming
fun decodeLargeFile(inputFile: java.io.File, outputFile: java.io.File): Boolean {
return try {
java.io.FileInputStream(inputFile).use { inputStream ->
java.io.FileOutputStream(outputFile).use { outputStream ->
val decoder = Base64.getDecoder().wrap(inputStream)
val buffer = ByteArray(4096)
var bytesRead: Int
while (decoder.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}
decoder.close()
}
}
true
} catch (e: Exception) {
println("Error decoding large file: ${e.message}")
false
}
}
}
// 5. Base64 Validation and Utilities
class Base64Utilities {
// Validate Base64 string
fun isValidBase64(input: String): Boolean {
return try {
Base64.getDecoder().decode(input)
true
} catch (e: IllegalArgumentException) {
false
}
}
// Check if URL-safe Base64
fun isValidUrlSafeBase64(input: String): Boolean {
return try {
Base64.getUrlDecoder().decode(input)
true
} catch (e: IllegalArgumentException) {
false
}
}
// Remove padding from Base64
fun removePadding(encoded: String): String {
return encoded.trimEnd('=')
}
// Add padding to Base64
fun addPadding(encoded: String): String {
val paddingLength = (4 - (encoded.length % 4)) % 4
return encoded + "=".repeat(paddingLength)
}
// Convert standard Base64 to URL-safe
fun toUrlSafe(encoded: String): String {
return encoded
.replace("+", "-")
.replace("/", "_")
.trimEnd('=')
}
// Convert URL-safe to standard Base64
fun fromUrlSafe(encoded: String): String {
var result = encoded
.replace("-", "+")
.replace("_", "/")
// Add padding
val paddingLength = (4 - (result.length % 4)) % 4
result += "=".repeat(paddingLength)
return result
}
}
// 6. Base64 for Data URLs
class DataUrlBase64 {
// Create data URL for image
fun createImageDataUrl(imageBytes: ByteArray, mimeType: String = "image/png"): String {
val base64 = Base64.getEncoder().encodeToString(imageBytes)
return "data:$mimeType;base64,$base64"
}
// Create data URL for text
fun createTextDataUrl(text: String, mimeType: String = "text/plain"): String {
val base64 = Base64.getEncoder().encodeToString(text.toByteArray())
return "data:$mimeType;base64,$base64"
}
// Extract Base64 from data URL
fun extractFromDataUrl(dataUrl: String): String? {
val prefix = "base64,"
val index = dataUrl.indexOf(prefix)
return if (index != -1) {
dataUrl.substring(index + prefix.length)
} else {
null
}
}
// Parse data URL
fun parseDataUrl(dataUrl: String): Pair<String, String>? {
val match = Regex("data:([^;]+);base64,(.+)").find(dataUrl)
return match?.let {
val mimeType = it.groupValues[1]
val base64 = it.groupValues[2]
mimeType to base64
}
}
}
// 7. Base64 Hash and Checksum
class Base64Hash {
// Encode MD5 hash as Base64
fun md5Base64(input: String): String {
val digest = java.security.MessageDigest.getInstance("MD5")
val hash = digest.digest(input.toByteArray())
return Base64.getEncoder().encodeToString(hash)
}
// Encode SHA-256 hash as Base64
fun sha256Base64(input: String): String {
val digest = java.security.MessageDigest.getInstance("SHA-256")
val hash = digest.digest(input.toByteArray())
return Base64.getEncoder().encodeToString(hash)
}
// Create Basic Authentication header
fun createBasicAuth(username: String, password: String): String {
val credentials = "$username:$password"
val encoded = Base64.getEncoder().encodeToString(credentials.toByteArray())
return "Basic $encoded"
}
// Parse Basic Authentication
fun parseBasicAuth(header: String): Pair<String, String>? {
if (!header.startsWith("Basic ")) {
return null
}
val encoded = header.substring(6)
val decoded = String(Base64.getDecoder().decode(encoded))
val parts = decoded.split(":", limit = 2)
return if (parts.size == 2) {
parts[0] to parts[1]
} else {
null
}
}
}
// Main demonstration
fun demonstrateBase64Encoding() {
println("=== Android Kotlin Base64 Encoding Examples ===\n")
// 1. Basic encoding/decoding
println("--- 1. Basic Encoding/Decoding ---")
val basicBase64 = BasicBase64()
val text = "Hello, World!"
val encoded = basicBase64.encodeToString(text)
println("Original: $text")
println("Encoded: $encoded")
val decoded = basicBase64.decodeString(encoded)
println("Decoded: $decoded")
// 2. URL-safe encoding
println("\n--- 2. URL-Safe Encoding ---")
val urlText = "Hello, World! This is a test."
val urlEncoded = basicBase64.encodeUrlSafe(urlText)
println("URL-safe encoded: $urlEncoded")
val urlDecoded = basicBase64.decodeUrlSafe(urlEncoded)
println("URL-safe decoded: $urlDecoded")
// 3. Binary data
println("\n--- 3. Binary Data ---")
val binaryBase64 = BinaryBase64()
val imageData = byteArrayOf(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A) // PNG header
val imageEncoded = binaryBase64.encodeImage(imageData)
println("Image data encoded: $imageEncoded")
val imageDecoded = binaryBase64.decodeToImage(imageEncoded)
println("Image data decoded: ${imageDecoded.joinToString(",") { "0x${it.toString(16).uppercase()}" }}")
// 4. MIME encoding
println("\n--- 4. MIME Encoding ---")
val longText = "This is a very long text that will be split into multiple lines when using MIME encoding."
val mimeEncoded = binaryBase64.encodeMime(longText)
println("MIME encoded:")
println(mimeEncoded)
// 5. Utilities
println("\n--- 5. Utilities ---")
val utilities = Base64Utilities()
println("Is valid Base64: ${utilities.isValidBase64(encoded)}")
println("Is valid URL-safe: ${utilities.isValidUrlSafeBase64(urlEncoded)}")
val withPadding = "SGVsbG8="
println("\nRemove padding: ${utilities.removePadding(withPadding)}")
println("Add padding: ${utilities.addPadding(utilities.removePadding(withPadding))}")
val standardBase64 = "SGVsbG8rV29ybGQvVGVzdA=="
val urlSafe = utilities.toUrlSafe(standardBase64)
println("\nTo URL-safe: $urlSafe")
println("From URL-safe: ${utilities.fromUrlSafe(urlSafe)}")
// 6. Data URLs
println("\n--- 6. Data URLs ---")
val dataUrl = DataUrlBase64()
val textBytes = "Sample text".toByteArray()
val textDataUrl = dataUrl.createTextDataUrl(String(textBytes), "text/plain")
println("Text data URL: $textDataUrl")
val extracted = dataUrl.extractFromDataUrl(textDataUrl)
println("Extracted Base64: $extracted")
// 7. Hash and authentication
println("\n--- 7. Hash and Authentication ---")
val base64Hash = Base64Hash()
val md5Base64 = base64Hash.md5Base64(text)
println("MD5 Base64: $md5Base64")
val sha256Base64 = base64Hash.sha256Base64(text)
println("SHA-256 Base64: $sha256Base64")
val basicAuth = base64Hash.createBasicAuth("alice", "password123")
println("\nBasic Auth: $basicAuth")
val parsedAuth = base64Hash.parseBasicAuth(basicAuth)
println("Parsed Auth: ${parsedAuth?.first} / ${parsedAuth?.second}")
println("\n=== All Base64 Encoding Examples Completed ===")
}
💻 Вычисление Хеша kotlin
🟡 intermediate
⭐⭐⭐⭐
Вычислять хеши MD5, SHA-1, SHA-256 и SHA-512 для строк и файлов
⏱️ 30 min
🏷️ kotlin, android, cryptography, hash
Prerequisites:
Intermediate Kotlin, Cryptography basics
// Android Kotlin Hash Calculation Examples
// Using java.security package
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.io.File
import java.io.FileInputStream
// 1. String Hashing
class StringHasher {
// Calculate MD5 hash
fun md5(input: String): String {
return try {
val digest = MessageDigest.getInstance("MD5")
val hash = digest.digest(input.toByteArray())
bytesToHex(hash)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("MD5 not available", e)
}
}
// Calculate SHA-1 hash
fun sha1(input: String): String {
return try {
val digest = MessageDigest.getInstance("SHA-1")
val hash = digest.digest(input.toByteArray())
bytesToHex(hash)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("SHA-1 not available", e)
}
}
// Calculate SHA-256 hash
fun sha256(input: String): String {
return try {
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(input.toByteArray())
bytesToHex(hash)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("SHA-256 not available", e)
}
}
// Calculate SHA-512 hash
fun sha512(input: String): String {
return try {
val digest = MessageDigest.getInstance("SHA-512")
val hash = digest.digest(input.toByteArray())
bytesToHex(hash)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("SHA-512 not available", e)
}
}
// Calculate with salt
fun hashWithSalt(input: String, salt: String, algorithm: String = "SHA-256"): String {
val digest = MessageDigest.getInstance(algorithm)
digest.update(salt.toByteArray())
val hash = digest.digest(input.toByteArray())
return bytesToHex(hash)
}
// Helper: Convert bytes to hex string
private fun bytesToHex(bytes: ByteArray): String {
val hexString = StringBuilder()
for (byte in bytes) {
val hex = Integer.toHexString(0xff and byte.toInt())
if (hex.length == 1) hexString.append('0')
hexString.append(hex)
}
return hexString.toString()
}
// Helper: Convert bytes to hex string (alternative)
private fun bytesToHexAlternative(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it) }
}
}
// 2. File Hashing
class FileHasher {
// Calculate hash for file
fun hashFile(file: File, algorithm: String = "SHA-256"): String {
val digest = MessageDigest.getInstance(algorithm)
FileInputStream(file).use { fis ->
val buffer = ByteArray(8192)
var bytesRead: Int
while (fis.read(buffer).also { bytesRead = it } != -1) {
digest.update(buffer, 0, bytesRead)
}
}
val hash = digest.digest()
return bytesToHex(hash)
}
// Calculate MD5 of file
fun md5File(file: File): String {
return hashFile(file, "MD5")
}
// Calculate SHA-256 of file
fun sha256File(file: File): String {
return hashFile(file, "SHA-256")
}
// Calculate hash for large file with progress
fun hashFileWithProgress(
file: File,
algorithm: String = "SHA-256",
onProgress: (Long, Long) -> Unit
): String {
val digest = MessageDigest.getInstance(algorithm)
val fileSize = file.length()
var bytesProcessed = 0L
FileInputStream(file).use { fis ->
val buffer = ByteArray(8192)
var bytesRead: Int
while (fis.read(buffer).also { bytesRead = it } != -1) {
digest.update(buffer, 0, bytesRead)
bytesProcessed += bytesRead
onProgress(bytesProcessed, fileSize)
}
}
val hash = digest.digest()
return bytesToHex(hash)
}
private fun bytesToHex(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it) }
}
// Verify file integrity
fun verifyFileIntegrity(file: File, expectedHash: String, algorithm: String = "SHA-256"): Boolean {
val actualHash = hashFile(file, algorithm)
return actualHash.equals(expectedHash, ignoreCase = true)
}
}
// 3. Password Hashing
class PasswordHasher {
// Simple password hash (not for production - use bcrypt/argon2 instead)
fun hashPassword(password: String, salt: String): String {
val hasher = StringHasher()
return hasher.hashWithSalt(password, salt, "SHA-256")
}
// Generate random salt
fun generateSalt(length: Int = 32): String {
val bytes = ByteArray(length)
java.security.SecureRandom().nextBytes(bytes)
return bytesToHex(bytes)
}
private fun bytesToHex(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it) }
}
// Hash with iterations (slow hash)
fun hashWithIterations(password: String, salt: String, iterations: Int = 10000): String {
val digest = MessageDigest.getInstance("SHA-256")
var hash = (password + salt).toByteArray()
repeat(iterations) {
hash = digest.digest(hash)
}
return bytesToHex(hash)
}
private fun bytesToHex(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it) }
}
// Verify password
fun verifyPassword(password: String, salt: String, expectedHash: String): Boolean {
val actualHash = hashWithIterations(password, salt, 10000)
return actualHash.equals(expectedHash, ignoreCase = true)
}
}
// 4. HMAC (Hash-based Message Authentication Code)
class HmacHasher {
// Calculate HMAC-SHA256
fun hmacSha256(data: String, key: String): String {
val mac = javax.crypto.Mac.getInstance("HmacSHA256")
val secretKey = javax.crypto.spec.SecretKeySpec(key.toByteArray(), "HmacSHA256")
mac.init(secretKey)
val hmac = mac.doFinal(data.toByteArray())
return bytesToHex(hmac)
}
// Calculate HMAC-SHA512
fun hmacSha512(data: String, key: String): String {
val mac = javax.crypto.Mac.getInstance("HmacSHA512")
val secretKey = javax.crypto.spec.SecretKeySpec(key.toByteArray(), "HmacSHA512")
mac.init(secretKey)
val hmac = mac.doFinal(data.toByteArray())
return bytesToHex(hmac)
}
// Verify HMAC
fun verifyHmac(data: String, key: String, expectedHmac: String, algorithm: String = "HmacSHA256"): Boolean {
val actualHmac = when (algorithm) {
"HmacSHA256" -> hmacSha256(data, key)
"HmacSHA512" -> hmacSha512(data, key)
else -> throw IllegalArgumentException("Unsupported algorithm: $algorithm")
}
return actualHmac.equals(expectedHmac, ignoreCase = true)
}
private fun bytesToHex(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it) }
}
}
// 5. Hash Comparison and Utilities
class HashUtilities {
// Compare two hashes securely (prevent timing attacks)
fun secureCompare(hash1: String, hash2: String): Boolean {
return MessageDigest.isEqual(hash1.toByteArray(), hash2.toByteArray())
}
// Generate hash for checksum file
fun generateChecksum(file: File): String {
val hasher = FileHasher()
return hasher.sha256File(file)
}
// Create checksum file content
fun createChecksumContent(file: File): String {
val hash = FileHasher().sha256File(file)
return "${hash} ${file.name}"
}
// Parse checksum file
fun parseChecksumFile(checksumFile: File): Map<String, String> {
val checksums = mutableMapOf<String, String>()
checksumFile.forEachLine { line ->
val parts = line.split(" ")
if (parts.size == 2) {
checksums[parts[1]] = parts[0]
}
}
return checksums
}
// Verify checksums from file
fun verifyChecksums(directory: File, checksumFile: File): Boolean {
val checksums = parseChecksumFile(checksumFile)
for ((filename, expectedHash) in checksums) {
val file = File(directory, filename)
if (!file.exists()) {
println("File not found: $filename")
return false
}
val actualHash = FileHasher().sha256File(file)
if (!actualHash.equals(expectedHash, ignoreCase = true)) {
println("Checksum mismatch for $filename")
return false
}
}
return true
}
}
// 6. Hash-based Operations
class HashBasedOperations {
// Generate hash-based identifier
fun generateIdentifier(input: String): String {
val hash = StringHasher().sha256(input)
return hash.substring(0, 16)
}
// Create content-based hash for deduplication
fun contentHash(content: String): String {
return StringHasher().sha256(content)
}
// Hash-based cache key
fun createCacheKey(params: Map<String, Any>): String {
val paramString = params.toList()
.sortedBy { it.first }
.joinToString("&") { "${it.first}=${it.second}" }
return StringHasher().sha256(paramString)
}
// Hash-based URL shortener (simplified)
fun shortenUrl(url: String): String {
val hash = StringHasher().md5(url)
return hash.substring(0, 8)
}
// Bloom filter hash functions
fun bloomFilterHashes(item: String, numHashes: Int, filterSize: Int): List<Int> {
val hashes = mutableListOf<Int>()
val hash1 = StringHasher().sha256(item)
val hash2 = StringHasher().md5(item)
for (i in 0 until numHashes) {
val combined = hash1 + hash2 + i
val hash = StringHasher().sha256(combined)
val index = (hash.substring(0, 8).toInt(16) % filterSize)
hashes.add(index)
}
return hashes
}
}
// Main demonstration
fun demonstrateHashCalculation() {
println("=== Android Kotlin Hash Calculation Examples ===\n")
// 1. String hashing
println("--- 1. String Hashing ---")
val stringHasher = StringHasher()
val text = "Hello, World!"
println("Text: $text")
println("MD5: ${stringHasher.md5(text)}")
println("SHA-1: ${stringHasher.sha1(text)}")
println("SHA-256: ${stringHasher.sha256(text)}")
println("SHA-512: ${stringHasher.sha512(text)}")
// Hash with salt
val salt = "random_salt_123"
println("\nHashed with salt '$salt':")
println("${stringHasher.hashWithSalt(text, salt)}")
// 2. Password hashing
println("\n--- 2. Password Hashing ---")
val passwordHasher = PasswordHasher()
val password = "SecurePassword123!"
val generatedSalt = passwordHasher.generateSalt()
println("Password: $password")
println("Generated salt: $generatedSalt")
val hashedPassword = passwordHasher.hashWithIterations(password, generatedSalt, 10000)
println("Hashed password: $hashedPassword")
val isValid = passwordHasher.verifyPassword(password, generatedSalt, hashedPassword)
println("Password verification: $isValid")
// 3. HMAC
println("\n--- 3. HMAC ---")
val hmacHasher = HmacHasher()
val data = "Important message"
val key = "secret_key"
val hmac = hmacHasher.hmacSha256(data, key)
println("Data: $data")
println("HMAC-SHA256: $hmac")
val hmacVerified = hmacHasher.verifyHmac(data, key, hmac)
println("HMAC verification: $hmacVerified")
// 4. File hashing
println("\n--- 4. File Hashing ---")
val fileHasher = FileHasher()
// Note: In real usage, you'd have actual files
println("File hashing methods:")
println(" - hashFile(): Calculate hash for any file")
println(" - md5File(): Calculate MD5 of file")
println(" - sha256File(): Calculate SHA-256 of file")
println(" - hashFileWithProgress(): Track progress for large files")
println(" - verifyFileIntegrity(): Verify file against expected hash")
// 5. Hash utilities
println("\n--- 5. Hash Utilities ---")
val hashUtils = HashUtilities()
val hash1 = "abc123"
val hash2 = "abc123"
val hash3 = "xyz789"
println("Secure compare 'abc123' vs 'abc123': ${hashUtils.secureCompare(hash1, hash2)}")
println("Secure compare 'abc123' vs 'xyz789': ${hashUtils.secureCompare(hash1, hash3)}")
// 6. Hash-based operations
println("\n--- 6. Hash-Based Operations ---")
val hashOps = HashBasedOperations()
val identifier = hashOps.generateIdentifier("unique_item_123")
println("Generated identifier: $identifier")
val cacheKey = hashOps.createCacheKey(mapOf(
"user" to "alice",
"page" to 1,
"limit" to 20
))
println("Cache key: $cacheKey")
val shortUrl = hashOps.shortenUrl("https://example.com/very/long/url/path")
println("Shortened URL: $shortUrl")
val bloomHashes = hashOps.bloomFilterHashes("test_item", 3, 1000)
println("Bloom filter hashes: $bloomHashes")
println("\n=== All Hash Calculation Examples Completed ===")
}
💻 AES Шифрование kotlin
🔴 complex
⭐⭐⭐⭐⭐
Шифровать и расшифровывать данные, используя AES с различными режимами и схемами заполнения
⏱️ 40 min
🏷️ kotlin, android, cryptography, encryption
Prerequisites:
Advanced Kotlin, Cryptography knowledge
// Android Kotlin AES Encryption Examples
// Using javax.crypto package
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.PBEKeySpec
import java.security.SecureRandom
import java.security.spec.KeySpec
import java.util.Base64
// 1. Basic AES Encryption
class BasicAesEncryption {
// Generate AES key
fun generateKey(keySize: Int = 256): SecretKey {
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(keySize)
return keyGen.generateKey()
}
// Encrypt with AES/GCM/NoPadding
fun encryptGCM(plainText: String, key: SecretKey): Pair<String, String> {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
// Generate random IV
val iv = ByteArray(12)
SecureRandom().nextBytes(iv)
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec)
val cipherText = cipher.doFinal(plainText.toByteArray())
// Return IV and ciphertext as Base64
val ivBase64 = Base64.getEncoder().encodeToString(iv)
val cipherTextBase64 = Base64.getEncoder().encodeToString(cipherText)
return Pair(ivBase64, cipherTextBase64)
}
// Decrypt with AES/GCM/NoPadding
fun decryptGCM(cipherText: String, iv: String, key: SecretKey): String {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val ivBytes = Base64.getDecoder().decode(iv)
val cipherTextBytes = Base64.getDecoder().decode(cipherText)
val ivSpec = IvParameterSpec(ivBytes)
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec)
val plainText = cipher.doFinal(cipherTextBytes)
return String(plainText)
}
// Encrypt with AES/CBC/PKCS5Padding
fun encryptCBC(plainText: String, key: SecretKey): Pair<String, String> {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
// Generate random IV (16 bytes for CBC)
val iv = ByteArray(16)
SecureRandom().nextBytes(iv)
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec)
val cipherText = cipher.doFinal(plainText.toByteArray())
val ivBase64 = Base64.getEncoder().encodeToString(iv)
val cipherTextBase64 = Base64.getEncoder().encodeToString(cipherText)
return Pair(ivBase64, cipherTextBase64)
}
// Decrypt with AES/CBC/PKCS5Padding
fun decryptCBC(cipherText: String, iv: String, key: SecretKey): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivBytes = Base64.getDecoder().decode(iv)
val cipherTextBytes = Base64.getDecoder().decode(cipherText)
val ivSpec = IvParameterSpec(ivBytes)
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec)
val plainText = cipher.doFinal(cipherTextBytes)
return String(plainText)
}
}
// 2. Password-Based Encryption
class PasswordBasedEncryption {
// Derive key from password
fun deriveKeyFromPassword(
password: String,
salt: ByteArray,
keySize: Int = 256,
iterations: Int = 65536
): SecretKey {
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val spec = PBEKeySpec(
password.toCharArray(),
salt,
iterations,
keySize
)
val key = factory.generateSecret(spec)
return SecretKeySpec(key.encoded, "AES")
}
// Generate random salt
fun generateSalt(size: Int = 16): ByteArray {
val salt = ByteArray(size)
SecureRandom().nextBytes(salt)
return salt
}
// Encrypt with password
fun encryptWithPassword(plainText: String, password: String): Triple<String, String, String> {
val salt = generateSalt()
val key = deriveKeyFromPassword(password, salt)
val aes = BasicAesEncryption()
val (iv, cipherText) = aes.encryptGCM(plainText, key)
val saltBase64 = Base64.getEncoder().encodeToString(salt)
return Triple(saltBase64, iv, cipherText)
}
// Decrypt with password
fun decryptWithPassword(
cipherText: String,
iv: String,
salt: String,
password: String
): String {
val saltBytes = Base64.getDecoder().decode(salt)
val key = deriveKeyFromPassword(password, saltBytes)
val aes = BasicAesEncryption()
return aes.decryptGCM(cipherText, iv, key)
}
// Generate key with specific iterations
fun generateStrongKey(password: String, iterations: Int = 100000): SecretKey {
val salt = generateSalt()
return deriveKeyFromPassword(password, salt, 256, iterations)
}
}
// 3. File Encryption
class FileEncryption {
// Encrypt file
fun encryptFile(
inputFile: java.io.File,
outputFile: java.io.File,
key: SecretKey
): Boolean {
return try {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val iv = ByteArray(12)
SecureRandom().nextBytes(iv)
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec)
// Write IV first
java.io.FileOutputStream(outputFile).use { fos ->
fos.write(iv)
// Encrypt file content
java.io.FileInputStream(inputFile).use { fis ->
val cipherStream = javax.crypto.CipherOutputStream(fos, cipher)
val buffer = ByteArray(4096)
var bytesRead: Int
while (fis.read(buffer).also { bytesRead = it } != -1) {
cipherStream.write(buffer, 0, bytesRead)
}
cipherStream.close()
}
}
true
} catch (e: Exception) {
println("Error encrypting file: ${e.message}")
false
}
}
// Decrypt file
fun decryptFile(
inputFile: java.io.File,
outputFile: java.io.File,
key: SecretKey
): Boolean {
return try {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
// Read IV first
java.io.FileInputStream(inputFile).use { fis ->
val iv = ByteArray(12)
fis.read(iv)
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec)
// Decrypt file content
java.io.FileOutputStream(outputFile).use { fos ->
val cipherStream = javax.crypto.CipherInputStream(fis, cipher)
val buffer = ByteArray(4096)
var bytesRead: Int
while (cipherStream.read(buffer).also { bytesRead = it } != -1) {
fos.write(buffer, 0, bytesRead)
}
cipherStream.close()
}
}
true
} catch (e: Exception) {
println("Error decrypting file: ${e.message}")
false
}
}
}
// 4. String Encryption Utilities
class StringEncryptionUtils {
private val aes = BasicAesEncryption()
private val passwordEnc = PasswordBasedEncryption()
// Encrypt string to Base64 (combined IV + ciphertext)
fun encryptStringToBase64(plainText: String, password: String): String {
val (salt, iv, cipherText) = passwordEnc.encryptWithPassword(plainText, password)
// Combine salt + iv + ciphertext
val combined = "$salt:$iv:$cipherText"
return Base64.getEncoder().encodeToString(combined.toByteArray())
}
// Decrypt string from Base64
fun decryptStringFromBase64(encoded: String, password: String): String {
val combined = String(Base64.getDecoder().decode(encoded))
val parts = combined.split(":")
if (parts.size != 3) {
throw IllegalArgumentException("Invalid encrypted format")
}
val (salt, iv, cipherText) = parts
return passwordEnc.decryptWithPassword(cipherText, iv, salt, password)
}
// Encrypt multiple strings
fun encryptStrings(strings: List<String>, key: SecretKey): List<Pair<String, String>> {
return strings.map { text ->
val (iv, cipherText) = aes.encryptGCM(text, key)
text to cipherText
}
}
// Decrypt multiple strings
fun decryptStrings(encryptedData: List<Pair<String, String>>, key: SecretKey): List<String> {
return encryptedData.map { (original, cipherText) ->
// Assuming IV is stored separately or embedded
// For simplicity, using same IV for demo
aes.decryptGCM(cipherText, "base64_iv_placeholder", key)
}
}
}
// 5. Advanced AES Operations
class AdvancedAesOperations {
// Encrypt with custom IV
fun encryptWithCustomIV(plainText: String, key: SecretKey, iv: ByteArray): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec)
val cipherText = cipher.doFinal(plainText.toByteArray())
return Base64.getEncoder().encodeToString(cipherText)
}
// Encrypt with AES-ECB (not recommended for production)
fun encryptECB(plainText: String, key: SecretKey): String {
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, key)
val cipherText = cipher.doFinal(plainText.toByteArray())
return Base64.getEncoder().encodeToString(cipherText)
}
// Decrypt with AES-ECB
fun decryptECB(cipherText: String, key: SecretKey): String {
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, key)
val cipherTextBytes = Base64.getDecoder().decode(cipherText)
val plainText = cipher.doFinal(cipherTextBytes)
return String(plainText)
}
// Generate AES key from bytes
fun keyFromBytes(keyBytes: ByteArray): SecretKey {
require(keyBytes.size == 16 || keyBytes.size == 24 || keyBytes.size == 32) {
"Key must be 16, 24, or 32 bytes"
}
return SecretKeySpec(keyBytes, "AES")
}
// Generate AES key from password (simple version)
fun keyFromPassword(password: String, keySize: Int = 256): SecretKey {
val keyBytes = password.toByteArray().copyOf(keySize / 8)
return keyFromBytes(keyBytes)
}
}
// 6. Secure Key Management
class KeyManager {
// Store key securely (in Android Keystore)
fun storeKeyInKeystore(alias: String, key: SecretKey): Boolean {
// Note: This requires Android Keystore integration
// Simplified example
return try {
// In production, use AndroidKeyStore
val keyStore = java.security.KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
if (!keyStore.containsAlias(alias)) {
keyStore.setEntry(
alias,
java.security.KeyStore.SecretKeyEntry(key),
java.security.KeyProtection.Builder(
javax.crypto.spec.SecretKeySpec(key.encoded, "AES")
).build()
)
}
true
} catch (e: Exception) {
println("Error storing key: ${e.message}")
false
}
}
// Load key from keystore
fun loadKeyFromKeystore(alias: String): SecretKey? {
return try {
val keyStore = java.security.KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
val entry = keyStore.getEntry(alias, null) as? java.security.KeyStore.SecretKeyEntry
entry?.secretKey
} catch (e: Exception) {
println("Error loading key: ${e.message}")
null
}
}
// Generate and store key
fun generateAndStoreKey(alias: String, keySize: Int = 256): SecretKey? {
val key = KeyGenerator.getInstance("AES").apply {
init(keySize)
}.generateKey()
return if (storeKeyInKeystore(alias, key)) {
key
} else {
null
}
}
}
// Main demonstration
fun demonstrateAesEncryption() {
println("=== Android Kotlin AES Encryption Examples ===\n")
// 1. Basic encryption
println("--- 1. Basic AES Encryption ---")
val aes = BasicAesEncryption()
val key = aes.generateKey(256)
println("Generated AES key: ${key.algorithm}")
val plainText = "This is a secret message!"
println("Plaintext: $plainText")
val (iv, cipherText) = aes.encryptGCM(plainText, key)
println("\nEncrypted with AES/GCM:")
println("IV: $iv")
println("Ciphertext: $cipherText")
val decrypted = aes.decryptGCM(cipherText, iv, key)
println("\nDecrypted: $decrypted")
// 2. CBC mode
println("\n--- 2. CBC Mode ---")
val (ivCbc, cipherTextCbc) = aes.encryptCBC(plainText, key)
println("Encrypted with AES/CBC:")
println("Ciphertext: $cipherTextCbc")
val decryptedCbc = aes.decryptCBC(cipherTextCbc, ivCbc, key)
println("Decrypted: $decryptedCbc")
// 3. Password-based encryption
println("\n--- 3. Password-Based Encryption ---")
val passwordEnc = PasswordBasedEncryption()
val password = "SecurePassword123!"
val (salt, ivPbe, cipherTextPbe) = passwordEnc.encryptWithPassword(plainText, password)
println("Encrypted with password:")
println("Salt: $salt")
println("Ciphertext: $cipherTextPbe")
val decryptedPbe = passwordEnc.decryptWithPassword(cipherTextPbe, ivPbe, salt, password)
println("Decrypted: $decryptedPbe")
// 4. String utilities
println("\n--- 4. String Encryption Utilities ---")
val stringUtils = StringEncryptionUtils()
val base64Encrypted = stringUtils.encryptStringToBase64("Hello, World!", password)
println("Base64 encrypted: $base64Encrypted")
val base64Decrypted = stringUtils.decryptStringFromBase64(base64Encrypted, password)
println("Decrypted: $base64Decrypted")
// 5. Advanced operations
println("\n--- 5. Advanced Operations ---")
val advancedOps = AdvancedAesOperations()
val customIv = ByteArray(16)
SecureRandom().nextBytes(customIv)
val customEncrypted = advancedOps.encryptWithCustomIV(plainText, key, customIv)
println("Encrypted with custom IV: $customEncrypted")
// Note: File encryption requires actual files
println("\n--- 6. File Encryption ---")
println("File encryption methods:")
println(" - encryptFile(): Encrypt entire file")
println(" - decryptFile(): Decrypt encrypted file")
// 7. Key management
println("\n--- 7. Key Management ---")
val keyManager = KeyManager()
println("Key management methods:")
println(" - generateAndStoreKey(): Generate and store in Android Keystore")
println(" - loadKeyFromKeystore(): Load stored key")
println(" - keyFromBytes(): Create key from byte array")
println(" - keyFromPassword(): Derive key from password")
println("\n=== All AES Encryption Examples Completed ===")
}