7
7
import android .os .CancellationSignal ;
8
8
import android .security .keystore .KeyGenParameterSpec ;
9
9
import android .security .keystore .KeyInfo ;
10
+ import android .security .keystore .KeyPermanentlyInvalidatedException ;
10
11
import android .security .keystore .KeyProperties ;
11
12
import android .support .annotation .NonNull ;
12
13
import android .util .Base64 ;
@@ -212,36 +213,40 @@ private void putExtra(String key, Object value, SharedPreferences mSharedPrefere
212
213
* Android Keystore.
213
214
*/
214
215
private void initKeyStore () {
215
- if (android .os .Build .VERSION .SDK_INT < android .os .Build .VERSION_CODES .M ) {
216
- return ;
217
- }
218
216
try {
219
217
mKeyStore = KeyStore .getInstance (ANDROID_KEYSTORE_PROVIDER );
220
218
mKeyStore .load (null );
221
219
222
220
// Check if a generated key exists under the KEY_ALIAS_AES .
223
221
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 ();
240
223
}
241
224
} catch (Exception e ) {
242
225
}
243
226
}
244
227
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
+
245
250
private void putExtraWithAES (final String key , final String value , final SharedPreferences mSharedPreferences , final Promise pm , Cipher cipher ) {
246
251
if (android .os .Build .VERSION .SDK_INT >= android .os .Build .VERSION_CODES .M && hasSetupFingerprint ()) {
247
252
try {
@@ -250,6 +255,7 @@ private void putExtraWithAES(final String key, final String value, final SharedP
250
255
cipher = Cipher .getInstance (AES_DEFAULT_TRANSFORMATION );
251
256
cipher .init (Cipher .ENCRYPT_MODE , secretKey );
252
257
258
+
253
259
// Retrieve information about the SecretKey from the KeyStore.
254
260
SecretKeyFactory factory = SecretKeyFactory .getInstance (
255
261
secretKey .getAlgorithm (), ANDROID_KEYSTORE_PROVIDER );
@@ -303,6 +309,14 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
303
309
304
310
putExtra (key , result , mSharedPreferences );
305
311
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 );
306
320
} catch (SecurityException e ) {
307
321
pm .reject (e );
308
322
} catch (Exception e ) {
@@ -375,6 +389,14 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
375
389
}
376
390
byte [] decryptedBytes = cipher .doFinal (cipherBytes );
377
391
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 );
378
400
} catch (SecurityException e ) {
379
401
pm .reject (e );
380
402
} catch (Exception e ) {
@@ -384,4 +406,4 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
384
406
pm .reject ("Fingerprint not supported" , "Fingerprint not supported" );
385
407
}
386
408
}
387
- }
409
+ }
0 commit comments