77import android .os .CancellationSignal ;
88import android .security .keystore .KeyGenParameterSpec ;
99import android .security .keystore .KeyInfo ;
10+ import android .security .keystore .KeyPermanentlyInvalidatedException ;
1011import android .security .keystore .KeyProperties ;
1112import android .support .annotation .NonNull ;
1213import android .util .Base64 ;
@@ -212,36 +213,40 @@ private void putExtra(String key, Object value, SharedPreferences mSharedPrefere
212213 * Android Keystore.
213214 */
214215 private void initKeyStore () {
215- if (android .os .Build .VERSION .SDK_INT < android .os .Build .VERSION_CODES .M ) {
216- return ;
217- }
218216 try {
219217 mKeyStore = KeyStore .getInstance (ANDROID_KEYSTORE_PROVIDER );
220218 mKeyStore .load (null );
221219
222220 // Check if a generated key exists under the KEY_ALIAS_AES .
223221 if (!mKeyStore .containsAlias (KEY_ALIAS_AES )) {
224- KeyGenerator keyGenerator = KeyGenerator .getInstance (
225- KeyProperties .KEY_ALGORITHM_AES , ANDROID_KEYSTORE_PROVIDER );
226-
227- KeyGenParameterSpec .Builder builder = null ;
228- builder = new KeyGenParameterSpec .Builder (
229- KEY_ALIAS_AES ,
230- KeyProperties .PURPOSE_ENCRYPT | KeyProperties .PURPOSE_DECRYPT );
231-
232- builder .setBlockModes (KeyProperties .BLOCK_MODE_CBC )
233- .setKeySize (256 )
234- .setEncryptionPaddings (KeyProperties .ENCRYPTION_PADDING_PKCS7 )
235- // forces user authentication with fingerprint
236- .setUserAuthenticationRequired (true );
237-
238- keyGenerator .init (builder .build ());
239- keyGenerator .generateKey ();
222+ prepareKey ();
240223 }
241224 } catch (Exception e ) {
242225 }
243226 }
244227
228+ private void prepareKey () throws Exception {
229+ if (android .os .Build .VERSION .SDK_INT < android .os .Build .VERSION_CODES .M ) {
230+ return ;
231+ }
232+ KeyGenerator keyGenerator = KeyGenerator .getInstance (
233+ KeyProperties .KEY_ALGORITHM_AES , ANDROID_KEYSTORE_PROVIDER );
234+
235+ KeyGenParameterSpec .Builder builder = null ;
236+ builder = new KeyGenParameterSpec .Builder (
237+ KEY_ALIAS_AES ,
238+ KeyProperties .PURPOSE_ENCRYPT | KeyProperties .PURPOSE_DECRYPT );
239+
240+ builder .setBlockModes (KeyProperties .BLOCK_MODE_CBC )
241+ .setKeySize (256 )
242+ .setEncryptionPaddings (KeyProperties .ENCRYPTION_PADDING_PKCS7 )
243+ // forces user authentication with fingerprint
244+ .setUserAuthenticationRequired (true );
245+
246+ keyGenerator .init (builder .build ());
247+ keyGenerator .generateKey ();
248+ }
249+
245250 private void putExtraWithAES (final String key , final String value , final SharedPreferences mSharedPreferences , final Promise pm , Cipher cipher ) {
246251 if (android .os .Build .VERSION .SDK_INT >= android .os .Build .VERSION_CODES .M && hasSetupFingerprint ()) {
247252 try {
@@ -250,6 +255,7 @@ private void putExtraWithAES(final String key, final String value, final SharedP
250255 cipher = Cipher .getInstance (AES_DEFAULT_TRANSFORMATION );
251256 cipher .init (Cipher .ENCRYPT_MODE , secretKey );
252257
258+
253259 // Retrieve information about the SecretKey from the KeyStore.
254260 SecretKeyFactory factory = SecretKeyFactory .getInstance (
255261 secretKey .getAlgorithm (), ANDROID_KEYSTORE_PROVIDER );
@@ -303,6 +309,14 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
303309
304310 putExtra (key , result , mSharedPreferences );
305311 pm .resolve (value );
312+ } catch (KeyPermanentlyInvalidatedException e ) {
313+ try {
314+ mKeyStore .deleteEntry (KEY_ALIAS_AES );
315+ prepareKey ();
316+ } catch (Exception keyResetError ) {
317+ pm .reject (keyResetError );
318+ }
319+ pm .reject (e );
306320 } catch (SecurityException e ) {
307321 pm .reject (e );
308322 } catch (Exception e ) {
@@ -375,6 +389,14 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
375389 }
376390 byte [] decryptedBytes = cipher .doFinal (cipherBytes );
377391 pm .resolve (new String (decryptedBytes ));
392+ } catch (KeyPermanentlyInvalidatedException e ) {
393+ try {
394+ mKeyStore .deleteEntry (KEY_ALIAS_AES );
395+ prepareKey ();
396+ } catch (Exception keyResetError ) {
397+ pm .reject (keyResetError );
398+ }
399+ pm .reject (e );
378400 } catch (SecurityException e ) {
379401 pm .reject (e );
380402 } catch (Exception e ) {
@@ -384,4 +406,4 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
384406 pm .reject ("Fingerprint not supported" , "Fingerprint not supported" );
385407 }
386408 }
387- }
409+ }
0 commit comments