66import android .security .KeyPairGeneratorSpec ;
77import android .security .keystore .KeyGenParameterSpec ;
88import android .security .keystore .KeyProperties ;
9+ import android .support .annotation .NonNull ;
910import android .util .Base64 ;
1011import android .util .Log ;
1112
12- import com .facebook .react .bridge .*;
13+ import com .facebook .react .bridge .Promise ;
14+ import com .facebook .react .bridge .ReactApplicationContext ;
15+ import com .facebook .react .bridge .ReactContextBaseJavaModule ;
16+ import com .facebook .react .bridge .ReactMethod ;
17+ import com .facebook .react .bridge .ReadableMap ;
18+ import com .facebook .react .bridge .WritableMap ;
19+ import com .facebook .react .bridge .WritableNativeMap ;
1320
1421import java .io .ByteArrayInputStream ;
1522import java .io .ByteArrayOutputStream ;
3138import javax .security .auth .x500 .X500Principal ;
3239
3340public class RNSensitiveInfoModule extends ReactContextBaseJavaModule {
34-
35- private SharedPreferences mSharedPreferences ;
41+
3642 private static final String AndroidKeyStore = "AndroidKeyStore" ;
37- private static final String RSA_MODE = "RSA/ECB/PKCS1Padding" ;
43+ private static final String RSA_MODE = "RSA/ECB/PKCS1Padding" ;
3844 private static final String AES_GCM = "AES/GCM/NoPadding" ;
3945 private static final String AES_ECB = "AES/ECB/PKCS7Padding" ;
4046 private static KeyStore keyStore ;
4147 private static final String KEY_ALIAS = "SHARED_PREFERENCE_KEY" ;
4248 private static final String ENCRYPTED_KEY = "ENCRYPTED_KEY" ;
4349 private static final String ENCRYPTION_SHARED_PREFERENCE_NAME = "ENCRYPTION_SHARED_PREFERENCE" ;
44- private static final byte [] FIXED_IV = {0 ,1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , 1 };
50+ private static final byte [] FIXED_IV = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , 1 };
4551 private static Key secretKey ;
46-
52+
4753 public RNSensitiveInfoModule (ReactApplicationContext reactContext ) {
4854 super (reactContext );
4955 try {
@@ -52,85 +58,65 @@ public RNSensitiveInfoModule(ReactApplicationContext reactContext) {
5258 Log .d ("RNSensitiveInfo" , e .getCause ().getMessage ());
5359 }
5460 }
55-
61+
5662 @ Override
5763 public String getName () {
5864 return "RNSensitiveInfo" ;
5965 }
60-
66+
6167 @ ReactMethod
6268 public void getItem (String key , ReadableMap options , Promise pm ) {
63-
64- String name = options .getString ("sharedPreferencesName" );
65- if (name == null ) {
66- name = "app" ;
67- }
68-
69- mSharedPreferences = getReactApplicationContext ().getSharedPreferences (name , Context .MODE_PRIVATE );
70- String value = mSharedPreferences .getString (key , null );
71- if (value != null ){
72- try {
69+
70+ String name = sharedPreferences (options );
71+
72+ String value = prefs (name ).getString (key , null );
73+ if (value != null ) {
74+ try {
7375 value = decrypt (value );
7476 } catch (Exception e ) {
7577 Log .d ("RNSensitiveInfo" , e .getCause ().getMessage ());
7678 }
7779 }
78-
80+
7981 pm .resolve (value );
8082 }
81-
83+
8284 @ ReactMethod
8385 public void setItem (String key , String value , ReadableMap options , Promise pm ) {
84-
85- String name = options .getString ("sharedPreferencesName" );
86- if (name == null ) {
87- name = "app" ;
88- }
89-
90- mSharedPreferences = getReactApplicationContext ().getSharedPreferences (name , Context .MODE_PRIVATE );
91-
86+
87+ String name = sharedPreferences (options );
88+
9289 try {
93- putExtra (key , value , mSharedPreferences );
90+ putExtra (key , value , prefs ( name ) );
9491 pm .resolve (null );
9592 } catch (Exception e ) {
9693 Log .d ("RNSensitiveInfo" , e .getCause ().getMessage ());
9794 pm .reject (e );
9895 }
9996 }
100-
101-
97+
98+
10299 @ ReactMethod
103100 public void deleteItem (String key , ReadableMap options , Promise pm ) {
104-
105- String name = options .getString ("sharedPreferencesName" );
106- if (name == null ) {
107- name = "app" ;
108- }
109-
110- mSharedPreferences = getReactApplicationContext ().getSharedPreferences (name , Context .MODE_PRIVATE );
111-
112- SharedPreferences .Editor editor = mSharedPreferences .edit ();
113-
101+
102+ String name = sharedPreferences (options );
103+
104+ SharedPreferences .Editor editor = prefs (name ).edit ();
105+
114106 editor .remove (key ).apply ();
115-
107+
116108 pm .resolve (null );
117109 }
118-
119-
120-
110+
111+
121112 @ ReactMethod
122113 public void getAllItems (ReadableMap options , Promise pm ) {
123-
124- String name = options .getString ("sharedPreferencesName" );
125- if (name == null ) {
126- name = "app" ;
127- }
128-
129- mSharedPreferences = getReactApplicationContext ().getSharedPreferences (name , Context .MODE_PRIVATE );
130-
131- Map <String , ?> allEntries = mSharedPreferences .getAll ();
114+
115+ String name = sharedPreferences (options );
116+
117+ Map <String , ?> allEntries = prefs (name ).getAll ();
132118 WritableMap resultData = new WritableNativeMap ();
133-
119+
134120 for (Map .Entry <String , ?> entry : allEntries .entrySet ()) {
135121 String value = entry .getValue ().toString ();
136122 try {
@@ -142,14 +128,27 @@ public void getAllItems(ReadableMap options, Promise pm) {
142128 }
143129 pm .resolve (resultData );
144130 }
145-
131+
132+ private SharedPreferences prefs (String name ) {
133+ return getReactApplicationContext ().getSharedPreferences (name , Context .MODE_PRIVATE );
134+ }
135+
136+ @ NonNull
137+ private String sharedPreferences (ReadableMap options ) {
138+ String name = options .hasKey ("sharedPreferencesName" ) ? options .getString ("sharedPreferencesName" ) : "app" ;
139+ if (name == null ) {
140+ name = "app" ;
141+ }
142+ return name ;
143+ }
144+
146145 private void putExtra (String key , String value , SharedPreferences mSharedPreferences ) throws Exception {
147146 SharedPreferences .Editor editor = mSharedPreferences .edit ();
148147 String encrypted = encrypt (value );
149148 editor .putString (key , encrypted ).apply ();
150149 }
151-
152- private void initKeyStore (Context context ) throws Exception {
150+
151+ private void initKeyStore (Context context ) throws Exception {
153152 keyStore = KeyStore .getInstance (AndroidKeyStore );
154153 keyStore .load (null );
155154 // Generate the RSA key pairs
@@ -158,31 +157,31 @@ private void initKeyStore(Context context) throws Exception{
158157 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
159158 KeyGenerator keyGenerator = KeyGenerator .getInstance (KeyProperties .KEY_ALGORITHM_AES , AndroidKeyStore );
160159 keyGenerator .init (
161- new KeyGenParameterSpec .Builder (KEY_ALIAS ,
162- KeyProperties .PURPOSE_ENCRYPT | KeyProperties .PURPOSE_DECRYPT )
163- .setBlockModes (KeyProperties .BLOCK_MODE_GCM )
164- .setEncryptionPaddings (KeyProperties .ENCRYPTION_PADDING_NONE )
165- .setRandomizedEncryptionRequired (false )
166- .build ());
160+ new KeyGenParameterSpec .Builder (KEY_ALIAS ,
161+ KeyProperties .PURPOSE_ENCRYPT | KeyProperties .PURPOSE_DECRYPT )
162+ .setBlockModes (KeyProperties .BLOCK_MODE_GCM )
163+ .setEncryptionPaddings (KeyProperties .ENCRYPTION_PADDING_NONE )
164+ .setRandomizedEncryptionRequired (false )
165+ .build ());
167166 keyGenerator .generateKey ();
168167 } else {
169168 Calendar start = Calendar .getInstance ();
170169 Calendar end = Calendar .getInstance ();
171170 end .add (Calendar .YEAR , 30 );
172171 KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec .Builder (context )
173- .setAlias (KEY_ALIAS )
174- .setSubject (new X500Principal ("CN=" + KEY_ALIAS ))
175- .setSerialNumber (BigInteger .TEN )
176- .setStartDate (start .getTime ())
177- .setEndDate (end .getTime ())
178- .build ();
172+ .setAlias (KEY_ALIAS )
173+ .setSubject (new X500Principal ("CN=" + KEY_ALIAS ))
174+ .setSerialNumber (BigInteger .TEN )
175+ .setStartDate (start .getTime ())
176+ .setEndDate (end .getTime ())
177+ .build ();
179178 KeyPairGenerator kpg = KeyPairGenerator .getInstance (KeyProperties .KEY_ALGORITHM_RSA , AndroidKeyStore );
180179 kpg .initialize (spec );
181180 kpg .generateKeyPair ();
182181 }
183-
182+
184183 }
185-
184+
186185 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
187186 secretKey = ((KeyStore .SecretKeyEntry ) keyStore .getEntry (KEY_ALIAS , null )).getSecretKey ();
188187 } else {
@@ -199,52 +198,52 @@ private void initKeyStore(Context context) throws Exception{
199198 edit .putString (ENCRYPTED_KEY , encryptedKeyB64 );
200199 edit .commit ();
201200 }
202-
201+
203202 byte [] encryptedKey = Base64 .decode (encryptedKeyB64 , Base64 .DEFAULT );
204203 byte [] key = rsaDecrypt (encryptedKey );
205204 secretKey = new SecretKeySpec (key , "AES" );
206205 }
207-
208-
206+
207+
209208 }
210-
211- private byte [] rsaEncrypt (byte [] secret ) throws Exception {
209+
210+ private byte [] rsaEncrypt (byte [] secret ) throws Exception {
212211 KeyStore .PrivateKeyEntry privateKeyEntry = (KeyStore .PrivateKeyEntry ) keyStore .getEntry (KEY_ALIAS , null );
213-
212+
214213 Cipher inputCipher = Cipher .getInstance (RSA_MODE , "AndroidOpenSSL" );
215214 inputCipher .init (Cipher .ENCRYPT_MODE , privateKeyEntry .getCertificate ().getPublicKey ());
216-
215+
217216 ByteArrayOutputStream outputStream = new ByteArrayOutputStream ();
218217 CipherOutputStream cipherOutputStream = new CipherOutputStream (outputStream , inputCipher );
219218 cipherOutputStream .write (secret );
220219 cipherOutputStream .close ();
221-
220+
222221 return outputStream .toByteArray ();
223222 }
224-
225- private byte [] rsaDecrypt (byte [] encrypted ) throws Exception {
223+
224+ private byte [] rsaDecrypt (byte [] encrypted ) throws Exception {
226225 KeyStore .PrivateKeyEntry privateKeyEntry = (KeyStore .PrivateKeyEntry ) keyStore .getEntry (KEY_ALIAS , null );
227-
226+
228227 Cipher outputCipher = Cipher .getInstance (RSA_MODE , "AndroidOpenSSL" );
229228 outputCipher .init (Cipher .DECRYPT_MODE , privateKeyEntry .getPrivateKey ());
230-
229+
231230 CipherInputStream cipherInputStream = new CipherInputStream (new ByteArrayInputStream (encrypted ), outputCipher );
232231 ArrayList <Byte > values = new ArrayList <>();
233232 int nextByte ;
234233 while ((nextByte = cipherInputStream .read ()) != -1 ) {
235- values .add ((byte )nextByte );
234+ values .add ((byte ) nextByte );
236235 }
237-
236+
238237 byte [] bytes = new byte [values .size ()];
239- for (int i = 0 ; i < bytes .length ; i ++) {
238+ for (int i = 0 ; i < bytes .length ; i ++) {
240239 bytes [i ] = values .get (i ).byteValue ();
241240 }
242241 return bytes ;
243242 }
244-
243+
245244 public String encrypt (String input ) throws Exception {
246245 byte [] bytes = input .getBytes ();
247-
246+
248247 Cipher c ;
249248 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
250249 c = Cipher .getInstance (AES_GCM );
@@ -254,15 +253,15 @@ public String encrypt(String input) throws Exception {
254253 c .init (Cipher .ENCRYPT_MODE , secretKey );
255254 }
256255 byte [] encodedBytes = c .doFinal (bytes );
257- String encryptedBase64Encoded = Base64 .encodeToString (encodedBytes , Base64 .DEFAULT );
256+ String encryptedBase64Encoded = Base64 .encodeToString (encodedBytes , Base64 .DEFAULT );
258257 return encryptedBase64Encoded ;
259258 }
260-
261-
259+
260+
262261 public String decrypt (String encrypted ) throws Exception {
263262 Cipher c ;
264263 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
265- c =Cipher .getInstance (AES_GCM );
264+ c = Cipher .getInstance (AES_GCM );
266265 c .init (Cipher .DECRYPT_MODE , secretKey , new GCMParameterSpec (128 , FIXED_IV ));
267266 } else {
268267 c = Cipher .getInstance (AES_ECB , "BC" );
0 commit comments