Skip to content

Commit 5b0180b

Browse files
authored
Merge pull request #81 from ycai2/feature/key-permanently-invalidated-exception
feature: handle exception by re-initialize key
2 parents 4a05ded + 2144bfc commit 5b0180b

File tree

1 file changed

+42
-20
lines changed

1 file changed

+42
-20
lines changed

android/src/main/java/br/com/classapp/RNSensitiveInfo/RNSensitiveInfoModule.java

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.os.CancellationSignal;
88
import android.security.keystore.KeyGenParameterSpec;
99
import android.security.keystore.KeyInfo;
10+
import android.security.keystore.KeyPermanentlyInvalidatedException;
1011
import android.security.keystore.KeyProperties;
1112
import android.support.annotation.NonNull;
1213
import 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

Comments
 (0)