Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BiometricPrompt crashes on Samsung S9 with Face unlock

I am using the new BiometricPrompt API in Android P (API 28) in my application. (I am actually using it inside a wrapper based on this project so that it functions on older devices too, but that is not relevant to the question.) This is working very well on all devices I have tested, except for the Samsung S9 with face unlock.

Even though the stock Android version of BiometricPrompt currently only implements fingerprint authentication, Samsung appears to have extended it to support Face Unlock as well. When I trigger biometric authentication in my app, the "bottom sheet" pops up with a face icon (instead of the fingerprint icon shown on all other devices) and at the top of the screen some text appears that says "no face detected". (Note that the icon shown here is provided by the operating system, not by me, so it is obviously of Samsung's design.)

According to the documentation, the BiometricPrompt is only supposed to close itself and call my onAuthenticationSucceeded method if the authentication has been successful. According to logcat, it looks like it has been successful:

I/IFaceDaemonCallback: BpFaceDaemonCallback onAcquired()
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=132] algo_out g=1.785 e_time=0.025 IsLLS=0x0 Ev=7.422 Bv=2.348 ProEv=7.348 Cvgd=1 lux=261, lls=0x0
E/CHI: [SS_ERR ]: [CHI_FACTORY ]: chxseccamerafactoryusecase.cpp: ExecuteCaptureRequest: 452: pMetaData is NULL
I/FaceHal: face_processFrontImage[614398]
I/FaceServiceWrapper: ss_face_processFrontImage(data_len = 614398, width = 480, height = 640, rotation = 270)
I/NativeFaceService: FaceService::processFrontImage - data_len (614398) width(480) height(640) rotation(270) format(2)
I/NativeFaceService: SEC_FR_SERVICE_AUTHENTICATE
I/sec_fr_engine_qsee: sec_fr_engine_on_authenticate_frame
D/sec_fr_engine_qsee: call QSEECom_send_cmd
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=133] algo_out g=1.785 e_time=0.025 IsLLS=0x0 Ev=7.422 Bv=2.352 ProEv=7.352 Cvgd=1 lux=261, lls=0x0
E/CHI: [SS_ERR ]: [CHI_FACTORY ]: chxseccamerafactoryusecase.cpp: ExecuteCaptureRequest: 452: pMetaData is NULL
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=134] algo_out g=1.864 e_time=0.025 IsLLS=0x0 Ev=7.359 Bv=2.332 ProEv=7.332 Cvgd=0 lux=262, lls=0x0
E/CHI: [SS_ERR ]: [CHI_FACTORY ]: chxseccamerafactoryusecase.cpp: ExecuteCaptureRequest: 452: pMetaData is NULL
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=135] algo_out g=1.910 e_time=0.025 IsLLS=0x0 Ev=7.324 Bv=2.324 ProEv=7.324 Cvgd=0 lux=262, lls=0x0
E/CHI: [SS_ERR ]: [CHI_FACTORY ]: chxseccamerafactoryusecase.cpp: ExecuteCaptureRequest: 452: pMetaData is NULL
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=136] algo_out g=1.920 e_time=0.025 IsLLS=0x0 Ev=7.316 Bv=2.316 ProEv=7.316 Cvgd=0 lux=262, lls=0x0
E/CHI: [SS_ERR ]: [CHI_FACTORY ]: chxseccamerafactoryusecase.cpp: ExecuteCaptureRequest: 452: pMetaData is NULL
I/sec_fr_engine_qsee: [Performance Log] QSEECom_send_cmd (129683) us in sec_fr_engine_on_authenticate_frame
D/sec_fr_engine_qsee: QSEECom_send_cmd Success
D/sec_fr_engine_qsee: return value from qsapp is 0
I/NativeFaceService: sec_fr_engine_on_authenticate_frame - status = [0], identified = [1], keepProcessing = [1]
I/NativeFaceService: identify succeeds
I/FaceServiceStorage: GetFileSize::Size of file: 196 bytes.
I/FaceServiceStorage: file size = 196
I/NativeFaceService: sid file length = 196
I/sec_fr_engine_qsee: sec_fr_engine_authenticated
D/sec_fr_engine_qsee: call QSEECom_send_cmd
I/SS_3A:  INFO: AEC: TsAec_process_get_aec_info: 650: [Id=137] algo_out g=1.936 e_time=0.025 IsLLS=0x0 Ev=7.305 Bv=2.301 ProEv=7.301 Cvgd=0 lux=263, lls=0x0
I/sec_fr_engine_qsee: [Performance Log] QSEECom_send_cmd (12414) us in sec_fr_engine_authenticated
D/sec_fr_engine_qsee: QSEECom_send_cmd Success
D/sec_fr_engine_qsee: return value from qsapp is 0
I/FaceServiceCallback: sendAuthenticated in
I/faced_Proxy: wrapped_object_length = 0
I/IFaceDaemonCallback: BpFaceDaemonCallback onAuthenticated() 
I/FaceServiceCallback: sendAuthenticated out
I/SemBioFaceServiceD: handleAuthenticated : 1
D/keystore: AddAuthenticationToken: timestamp = 168377203, time_received = 16675
I/SemBioFacePrompt: isSuccess = true

However, it then crashes with the following error:

E/keystore: getAuthToken failed: -3
W/System.err: javax.crypto.IllegalBlockSizeException
W/System.err:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
W/System.err:     at javax.crypto.Cipher.doFinal(Cipher.java:2055)
W/System.err:     at com.mycompany.myapp.activities.LoginActivity.onAuthenticationSuccessful(LoginActivity.java:560)
W/System.err:     at com.mycompany.common.security.BiometricCallbackV28.onAuthenticationSucceeded(BiometricCallbackV28.kt:18)
W/System.err:     at com.samsung.android.bio.face.SemBioFaceManager.sendAuthenticatedSucceeded(SemBioFaceManager.java:1507)
W/System.err:     at com.samsung.android.bio.face.SemBioFaceManager.access$2400(SemBioFaceManager.java:73)
W/System.err:     at com.samsung.android.bio.face.SemBioFaceManager$3.lambda$onAuthenticationSucceeded$1(SemBioFaceManager.java:1673)
W/System.err:     at com.samsung.android.bio.face.-$$Lambda$SemBioFaceManager$3$GGUPv9osWllaLwJM7Wg6GJEWK8E.run(Unknown Source:6)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:873)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loop(Looper.java:214)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6981)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
W/System.err: Caused by: android.security.KeyStoreException: Key user not authenticated
W/System.err:     at android.security.KeyStore.getKeyStoreException(KeyStore.java:1168)
W/System.err:     at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
W/System.err:     at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
W/System.err:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
W/System.err:   ... 14 more

According to the documentation, the success of the biometric authentication should have unlocked the keystore, but that has clearly not happened as shown by the Key user not authenticated message in the exception.

How can I get this working?

like image 833
Moshe Katz Avatar asked Apr 11 '19 14:04

Moshe Katz


People also ask

Is Samsung Face Unlock safe?

It's secure, but not as secure as a biometric authentication system like the fingerprint reader. The Galaxy S20 features a face unlock system that's identical on most Android phones.

Is Android Face Unlock secure?

Face authentication allows users to unlock their device simply by looking at the front of their device. Android 10 adds support for a new face authentication stack that can securely process camera frames, preserving security and privacy during face authentication on supported hardware.

Does Samsung a03 have Face Recognition?

Facial recognition is utilized to unlock the device. For optimal performance, ensure you are indoors or away from direct sunlight.


1 Answers

I had this same issue when attempting to use the BiometricPrompt APIs to authenticate users into my app. I reached out to Samsung technical support and they confirmed that Samsungs face recognition is not secure enough to unlock the Android Keystore.

This makes sense since the current Samsung Galaxy devices (S8, S9, S10) do not have the necessary hardware to do 3D imaging of a face (rumor has it that the Pixel 4 will). This reminds me of Samsungs first fingerprint implementation, on the S5 I believe, that did not meet Google's technical specifications and didn't work after upgrading to Marshmallow.

Below is the actual reply that I received from Samsung tech support:

For security reasons, Face Biometric can not update the keystore after authentication. So, SecurityException is shown when the application tries to make a keystore or sign by the keystore.

Currently, you can not use Face Biometric in your application to authenticate. Alternatively, you may guide the user to change Preferred Biometric to Fingerprint / Iris by showing a pop up (to open biometric preference setting) while getting these exceptions.

Thank you for your patience.

Curiously, I no longer see the crash on the Galaxy S10. The authentication just returns an error code. This may be even worse since it breaks their suggested fix. Ugh.

like image 78
SBerg413 Avatar answered Oct 06 '22 05:10

SBerg413