mogol / flutter_secure_storage

A Flutter plugin to store data in secure storage
https://pub.dartlang.org/packages/flutter_secure_storage
BSD 3-Clause "New" or "Revised" License
1.08k stars 339 forks source link

Feature request: Add Biometric Authentication Process as an Option #615

Open ttorii20 opened 9 months ago

ttorii20 commented 9 months ago

I am interested in adding a biometric authentication process for storage access authentication on each platform. Specifically, I'd like to introduce an option that requires biometric authentication when accessing the keychain on iOS and the keystore on Android.

Currently, flutter_secure_storage does not have such a feature, and there's no way to set this as an option. I believe adding the ability to set a biometric authentication process as an option would be beneficial.

Differences Across Platforms

The method of requesting biometric authentication from the user varies by platform. On iOS, the keychain handles the responsibility of controlling the biometric authentication dialog. In contrast, the Android keystore does not. Therefore, it's necessary to handle errors and display the biometric authentication dialog when required on Android.

For Android: I'd like to introduce options similar to setUserAuthenticationRequired and setUserAuthenticationValidityDurationSeconds. Here's a snippet to illustrate the desired functionality:

  private SharedPreferences initializeEncryptedSharedPreferencesManagerAuthenticationRequired(Context context,
            int authenticationValidityDurationSeconds) throws GeneralSecurityException, IOException {
        MasterKey key = new MasterKey.Builder(context, masterKeyAlias)
                .setKeyGenParameterSpec(
                        new KeyGenParameterSpec.Builder(masterKeyAlias,
                                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                                .setKeySize(256)
                                .setUserAuthenticationRequired(true)
                                .setUserAuthenticationValidityDurationSeconds(
                                    authenticationValidityDurationSeconds
                                )
                                .setInvalidatedByBiometricEnrollment(true)
                                .build())

For iOS: I'd like to introduce an option to set SecAccessControlCreateFlags.biometryCurrentSet for the keychain. Here's a snippet to illustrate the desired functionality:


if let accessControl = accessControl {
    var secAccessControlCreateFlags: SecAccessControlCreateFlags
    // ... other code ...
    }  else if accessControl == "biometryCurrentSet" {
        secAccessControlCreateFlags = SecAccessControlCreateFlags.biometryCurrentSet
    }  else {
        abort()
    }
    // ... other code ...
    accessControlCreateWithFlags = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                                                           attrAccessible,
                                                                           secAccessControlCreateFlags,
                                                                           &error)
 // ... other code ...
    var keychainQuery = baseQuery(key: key, groupId: groupId, accountName: accountName, synchronizable: synchronizable, returnData: nil, accessControl: accessControlCreateWithFlags)
   // ... other code ...
   return SecItemAdd(keychainQuery as CFDictionary, nil)

}

Anticipated Use Case

The primary use case I envision is during user login, where biometric authentication is performed to access the necessary information for authentication.

MacOMNI commented 8 months ago

That is a good idea!!

bogdannedelcu commented 7 months ago

@ttorii20 please add for Android also a flag to force the storage of the key on the TEE, not doing so would result in not creating the key. This is important for certification processes

ttorii20 commented 6 months ago

@bogdannedelcu Thanks for bringing this up. Just to be sure, are you suggesting we add an IsStrongBoxBacked flag for Android? And if it's about beefing up security, should we roll this into the main stream instead of a fork?

bogdannedelcu commented 6 months ago

Hi,

Any means to check the plugin did not save the key outside the hardware key store is fine.

Thanks!

În mar., 26 dec. 2023 la 02:55 Takahiro Torii @.***> a scris:

@bogdannedelcu https://github.com/bogdannedelcu Thanks for bringing this up. Just to be sure, are you suggesting we add an IsStrongBoxBacked flag for Android? And if it's about beefing up security, should we roll this into the main stream instead of a fork?

— Reply to this email directly, view it on GitHub https://github.com/mogol/flutter_secure_storage/issues/615#issuecomment-1869172817, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACAJSJDQEGRM67YSXADAQSDYLIN7LAVCNFSM6AAAAAA45VBPACVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNRZGE3TEOBRG4 . You are receiving this because you were mentioned.Message ID: @.***>

u382514 commented 4 months ago

I second this and would love to see this sooner than later. Seems like the the current approach is to retrieve a simple true/false from biometrics (using local_auth package?) and using that as the sole trust to access secure storage for the data. I'd like to not just get a true/false but that secure storage cannot literally access the keychain/keystore unless biometric auth has opened it up.

humphrey commented 4 weeks ago

+1 for this.