Skip to content

Commit c642962

Browse files
committed
Updated keystore branch
1 parent 1ea77d7 commit c642962

1 file changed

Lines changed: 67 additions & 14 deletions

File tree

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

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.facebook.react.bridge.WritableNativeMap;
2323
import com.facebook.react.modules.core.DeviceEventManagerModule;
2424

25+
import java.security.Key;
2526
import java.security.KeyStore;
2627
import java.util.HashMap;
2728
import java.util.Map;
@@ -30,6 +31,7 @@
3031
import javax.crypto.KeyGenerator;
3132
import javax.crypto.SecretKey;
3233
import javax.crypto.SecretKeyFactory;
34+
import javax.crypto.spec.GCMParameterSpec;
3335
import javax.crypto.spec.IvParameterSpec;
3436

3537
import br.com.classapp.RNSensitiveInfo.utils.AppConstants;
@@ -47,8 +49,12 @@ public class RNSensitiveInfoModule extends ReactContextBaseJavaModule {
4749
KeyProperties.BLOCK_MODE_CBC + "/" +
4850
KeyProperties.ENCRYPTION_PADDING_PKCS7;
4951

52+
private static final byte[] FIXED_IV = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1};
53+
private static final String KEY_ALIAS = "MySharedPreferenceKeyAlias";
5054
private static final String KEY_ALIAS_AES = "MyAesKeyAlias";
5155
private static final String DELIMITER = "]";
56+
private static final String AES_GCM = "AES/GCM/NoPadding";
57+
private static final String AES_ECB = "AES/ECB/PKCS7Padding";
5258

5359
private FingerprintManager mFingerprintManager;
5460
private KeyStore mKeyStore;
@@ -133,7 +139,11 @@ public void getItem(String key, ReadableMap options, Promise pm) {
133139

134140
decryptWithAes(value, showModal, strings, pm, null);
135141
} else {
136-
pm.resolve(value);
142+
try {
143+
pm.resolve(decrypt(value));
144+
} catch (Exception e) {
145+
pm.reject(e);
146+
}
137147
}
138148
}
139149

@@ -149,7 +159,7 @@ public void setItem(String key, String value, ReadableMap options, Promise pm) {
149159
putExtraWithAES(key, value, prefs(name), showModal, strings, pm, null);
150160
} else {
151161
try {
152-
putExtra(key, value, prefs(name));
162+
putExtra(key, encrypt(value), prefs(name));
153163
pm.resolve(value);
154164
} catch (Exception e) {
155165
Log.d("RNSensitiveInfo", e.getCause().getMessage());
@@ -208,19 +218,9 @@ private String sharedPreferences(ReadableMap options) {
208218
}
209219

210220

211-
private void putExtra(String key, Object value, SharedPreferences mSharedPreferences) {
221+
private void putExtra(String key, String value, SharedPreferences mSharedPreferences) {
212222
SharedPreferences.Editor editor = mSharedPreferences.edit();
213-
if (value instanceof String) {
214-
editor.putString(key, (String) value).apply();
215-
} else if (value instanceof Boolean) {
216-
editor.putBoolean(key, (Boolean) value).apply();
217-
} else if (value instanceof Integer) {
218-
editor.putInt(key, (Integer) value).apply();
219-
} else if (value instanceof Long) {
220-
editor.putLong(key, (Long) value).apply();
221-
} else if (value instanceof Float) {
222-
editor.putFloat(key, (Float) value).apply();
223-
}
223+
editor.putString(key, value).apply();
224224
}
225225

226226
/**
@@ -232,6 +232,17 @@ private void initKeyStore() {
232232
mKeyStore = KeyStore.getInstance(ANDROID_KEYSTORE_PROVIDER);
233233
mKeyStore.load(null);
234234

235+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
236+
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE_PROVIDER);
237+
keyGenerator.init(
238+
new KeyGenParameterSpec.Builder(KEY_ALIAS,
239+
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
240+
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
241+
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
242+
.setRandomizedEncryptionRequired(false)
243+
.build());
244+
keyGenerator.generateKey();
245+
}
235246
// Check if a generated key exists under the KEY_ALIAS_AES .
236247
if (!mKeyStore.containsAlias(KEY_ALIAS_AES)) {
237248
prepareKey();
@@ -244,6 +255,7 @@ private void prepareKey() throws Exception {
244255
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
245256
return;
246257
}
258+
247259
KeyGenerator keyGenerator = KeyGenerator.getInstance(
248260
KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE_PROVIDER);
249261

@@ -477,4 +489,45 @@ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult re
477489
pm.reject("Fingerprint not supported", "Fingerprint not supported");
478490
}
479491
}
492+
493+
public String encrypt(String input) throws Exception {
494+
495+
Key secretKey = ((KeyStore.SecretKeyEntry) mKeyStore.getEntry(KEY_ALIAS, null)).getSecretKey();
496+
byte[] bytes = input.getBytes();
497+
498+
Cipher c;
499+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
500+
c = Cipher.getInstance(AES_GCM);
501+
c.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, FIXED_IV));
502+
} else {
503+
c = Cipher.getInstance(AES_ECB, "BC");
504+
c.init(Cipher.ENCRYPT_MODE, secretKey);
505+
}
506+
byte[] encodedBytes = c.doFinal(bytes);
507+
String encryptedBase64Encoded = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
508+
return encryptedBase64Encoded;
509+
}
510+
511+
512+
public String decrypt(String encrypted) throws Exception {
513+
if (encrypted == null) {
514+
Exception cause = new RuntimeException("Invalid argument at decrypt function");
515+
throw new RuntimeException("encrypted argument can't be null", cause);
516+
}
517+
518+
Cipher c;
519+
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEYSTORE_PROVIDER);
520+
keyStore.load(null);
521+
Key secretKey = ((KeyStore.SecretKeyEntry) mKeyStore.getEntry(KEY_ALIAS, null)).getSecretKey();
522+
523+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
524+
c = Cipher.getInstance(AES_GCM);
525+
c.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, FIXED_IV));
526+
} else {
527+
c = Cipher.getInstance(AES_ECB, "BC");
528+
c.init(Cipher.DECRYPT_MODE, secretKey);
529+
}
530+
byte[] decodedBytes = c.doFinal(Base64.decode(encrypted, Base64.DEFAULT));
531+
return new String(decodedBytes);
532+
}
480533
}

0 commit comments

Comments
 (0)