Skip to content

An example Android app for generating key pairs in trusted execution environment to sign data requiring biometric authentication using Android keystore.

Notifications You must be signed in to change notification settings

mutkuensert/AndroidSignatureExample

Repository files navigation

androidkeystore.mp4

SignatureHelper.kt

/**
 * [SignatureHelper] provides utility methods to generate and manage key pairs in the Android KeyStore.
 * This class supports generating hardware-backed key pairs, signing data, verifying signatures, and managing KeyStore entries.
 *
 * @param alias The alias of the key entry in the KeyStore.
 * @param requireBiometricAuth Indicates if strong biometric authentication is required for accessing the key.
 * @param keyAlgorithm The algorithm to be used for key generation. Default is EC (Elliptic Curve).
 * @param signatureAlgorithm The algorithm to be used for signing data. Default is "SHA256withECDSA".
 * @param keyPairProvider The provider for the KeyStore. Default is "AndroidKeyStore".
 */
class SignatureHelper(
    val alias: String,
    val requireBiometricAuth: Boolean = false,
    val keyAlgorithm: String = KeyProperties.KEY_ALGORITHM_EC,
    val signatureAlgorithm: String = "SHA256withECDSA",
    val keyPairProvider: String = "AndroidKeyStore",
) {

    /**
     * Generates and returns key pair and if the pair is inside secure hardware or returns null and
     * removes the entry if the key pair isn't hardware backed or any error is occurred.
     */
    fun generateHardwareBackedKeyPair(): KeyPair? {
        // Method implementation
    }

    /**
     * Generates a key pair.
     * @return Null if any error is occurred, otherwise the key pair.
     */
    fun generateKeyPair(): KeyPair? {
        // Method implementation
    }

    /**
     *  Checks if a key entry with the specified alias exists in the KeyStore.
     */
    fun exists(): Boolean? {
        // Method implementation
    }

    /**
     * Deletes the key entry with the specified alias from the KeyStore.
     */
    fun deleteKeyStoreEntry(): Boolean {
        // Method implementation
    }

    /**
     * Signs the given data using the private key associated with the specified alias, returns null
     * if an error occurs.
     * If biometric authentication is required, it must be performed before signing the data.
     */
    fun signData(data: String): SignedData? {
        // Method implementation
    }

    /**
     * Encodes the public key of the given key pair to a Base64 string.
     */
    fun getPublicKeyBase64Encoded(keyPair: KeyPair): String {
        // Method implementation
    }

    /**
     * Verifies the given signature using the provided public key and data.
     */
    fun verifyData(publicKey: String, data: String, signature: String): Boolean {
        // Method implementation
    }

    /**
     * Verifies the given signature using the provided public key and data.
     */
    fun verifyData(publicKey: PublicKey, data: String, signature: String): Boolean {
        // Method implementation
    }

    /**
     * Converts a Base64 encoded public key string to a PublicKey object.
     */
    fun getPublicKeyFromString(publicKey: String): PublicKey? {
        // Method implementation
    }

    // Private methods and other internal logic
}

BiometricKeyPairHandler.kt

/**
 * BiometricKeyPairHandler manages the creation, deletion, and use of hardware-backed key pairs
 * with biometric authentication. This class utilizes [SignatureHelper] to interact with the Android KeyStore.
 *
 * @param alias The alias of the key entry in the KeyStore.
 */
class BiometricKeyPairHandler(alias: String) {
    private val signatureHelper = SignatureHelper(
        alias = alias,
        requireBiometricAuth = true
    )

    /**
     * If strong biometric is available then returns
     * [SignatureHelper.generateHardwareBackedKeyPair] otherwise returns null.
     */
    fun generateHardwareBackedKeyPair(activity: FragmentActivity): KeyPair? {
        if (!BiometricAuthHelper.isStrongBiometricAuthAvailable(activity)) {
            return null
        }

        return signatureHelper.generateHardwareBackedKeyPair()
    }

    fun deleteKeyPair(): Boolean {
        return signatureHelper.deleteKeyStoreEntry()
    }

    fun getPublicKeyBase64Encoded(keyPair: KeyPair): String {
        return signatureHelper.getPublicKeyBase64Encoded(keyPair)
    }

    fun verifyData(publicKey: String, data: String, signature: String): Boolean {
        return signatureHelper.verifyData(publicKey, data, signature)
    }

    /**
     * Authenticates the user via biometric authentication and signs the given data.
     * Calls the provided callback function with the signed data upon successful authentication.
     */
    fun authenticateAndSignData(
        data: String,
        activity: FragmentActivity,
        onAuthenticationSucceeded: (SignedData?) -> Unit
    ) {
        BiometricAuthHelper.authenticate(activity, onAuthenticationSucceeded = {
            onAuthenticationSucceeded(signatureHelper.signData(data))
        })
    }

    fun exists(): Boolean? {
        return signatureHelper.exists()
    }
}

About

An example Android app for generating key pairs in trusted execution environment to sign data requiring biometric authentication using Android keystore.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages