package com.biometriclogin import android.content.Context import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import java.security.KeyStore import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.SecretKey import javax.crypto.spec.GCMParameterSpec import android.util.Base64 class CryptoManager(private val context: Context) { private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } private fun getKey(): SecretKey { val existingKey = keyStore.getEntry("secret", null) as? KeyStore.SecretKeyEntry return existingKey?.secretKey ?: createKey() } private fun createKey(): SecretKey { return KeyGenerator.getInstance(ALGORITHM).apply { init( KeyGenParameterSpec.Builder( "secret", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT ) .setBlockModes(BLOCK_MODE) .setEncryptionPaddings(PADDING) .setUserAuthenticationRequired(false) .setRandomizedEncryptionRequired(true) .build() ) }.generateKey() } fun encrypt(bytes: ByteArray, associatedData: String): String { val cipher = Cipher.getInstance(TRANSFORMATION).apply { init(Cipher.ENCRYPT_MODE, getKey()) } val encryptedBytes = cipher.doFinal(bytes) val combined = cipher.iv + encryptedBytes return Base64.encodeToString(combined, Base64.DEFAULT) } fun decrypt(encryptedData: String, associatedData: String): ByteArray { val encryptedBytes = Base64.decode(encryptedData, Base64.DEFAULT) val iv = encryptedBytes.copyOfRange(0, IV_SIZE) val ciphertext = encryptedBytes.copyOfRange(IV_SIZE, encryptedBytes.size) val cipher = Cipher.getInstance(TRANSFORMATION).apply { init(Cipher.DECRYPT_MODE, getKey(), GCMParameterSpec(TAG_LENGTH_BIT, iv)) } return cipher.doFinal(ciphertext) } companion object { private const val ALGORITHM = KeyProperties.KEY_ALGORITHM_AES private const val BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM private const val PADDING = KeyProperties.ENCRYPTION_PADDING_NONE private const val TRANSFORMATION = "$ALGORITHM/$BLOCK_MODE/$PADDING" private const val TAG_LENGTH_BIT = 128 private const val IV_SIZE = 12 } }