🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Cryptographie Android Kotlin
Exemples de cryptographie Android Kotlin incluant le calcul de hachage, le chiffrement AES et le codage Base64
💻 Encodage Base64 kotlin
🟢 simple
⭐⭐
Encoder et décoder des données en utilisant Base64 avec diverses options et jeux de caractères
⏱️ 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 ===")
}
💻 Calcul de Hachage kotlin
🟡 intermediate
⭐⭐⭐⭐
Calculer les hachages MD5, SHA-1, SHA-256 et SHA-512 pour les chaînes et fichiers
⏱️ 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 ===")
}
💻 Chiffrement AES kotlin
🔴 complex
⭐⭐⭐⭐⭐
Chiffrer et déchiffrer des données en utilisant AES avec divers modes et schémas de remplissage
⏱️ 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 ===")
}