· 7 years ago · Mar 15, 2018, 01:16 PM
1Editor e = this.getPreferences(Context.MODE_PRIVATE).edit();
2e.putString("password", mPassword);
3e.commit();
4
5final SharedPreferences prefs = new ObscuredSharedPreferences(
6 this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE) );
7
8// eg.
9prefs.edit().putString("foo","bar").commit();
10prefs.getString("foo");
11
12/**
13 * Warning, this gives a false sense of security. If an attacker has enough access to
14 * acquire your password store, then he almost certainly has enough access to acquire your
15 * source binary and figure out your encryption key. However, it will prevent casual
16 * investigators from acquiring passwords, and thereby may prevent undesired negative
17 * publicity.
18 */
19public class ObscuredSharedPreferences implements SharedPreferences {
20 protected static final String UTF8 = "utf-8";
21 private static final char[] SEKRIT = ... ; // INSERT A RANDOM PASSWORD HERE.
22 // Don't use anything you wouldn't want to
23 // get out there if someone decompiled
24 // your app.
25
26
27 protected SharedPreferences delegate;
28 protected Context context;
29
30 public ObscuredSharedPreferences(Context context, SharedPreferences delegate) {
31 this.delegate = delegate;
32 this.context = context;
33 }
34
35 public class Editor implements SharedPreferences.Editor {
36 protected SharedPreferences.Editor delegate;
37
38 public Editor() {
39 this.delegate = ObscuredSharedPreferences.this.delegate.edit();
40 }
41
42 @Override
43 public Editor putBoolean(String key, boolean value) {
44 delegate.putString(key, encrypt(Boolean.toString(value)));
45 return this;
46 }
47
48 @Override
49 public Editor putFloat(String key, float value) {
50 delegate.putString(key, encrypt(Float.toString(value)));
51 return this;
52 }
53
54 @Override
55 public Editor putInt(String key, int value) {
56 delegate.putString(key, encrypt(Integer.toString(value)));
57 return this;
58 }
59
60 @Override
61 public Editor putLong(String key, long value) {
62 delegate.putString(key, encrypt(Long.toString(value)));
63 return this;
64 }
65
66 @Override
67 public Editor putString(String key, String value) {
68 delegate.putString(key, encrypt(value));
69 return this;
70 }
71
72 @Override
73 public void apply() {
74 delegate.apply();
75 }
76
77 @Override
78 public Editor clear() {
79 delegate.clear();
80 return this;
81 }
82
83 @Override
84 public boolean commit() {
85 return delegate.commit();
86 }
87
88 @Override
89 public Editor remove(String s) {
90 delegate.remove(s);
91 return this;
92 }
93 }
94
95 public Editor edit() {
96 return new Editor();
97 }
98
99
100 @Override
101 public Map<String, ?> getAll() {
102 throw new UnsupportedOperationException(); // left as an exercise to the reader
103 }
104
105 @Override
106 public boolean getBoolean(String key, boolean defValue) {
107 final String v = delegate.getString(key, null);
108 return v!=null ? Boolean.parseBoolean(decrypt(v)) : defValue;
109 }
110
111 @Override
112 public float getFloat(String key, float defValue) {
113 final String v = delegate.getString(key, null);
114 return v!=null ? Float.parseFloat(decrypt(v)) : defValue;
115 }
116
117 @Override
118 public int getInt(String key, int defValue) {
119 final String v = delegate.getString(key, null);
120 return v!=null ? Integer.parseInt(decrypt(v)) : defValue;
121 }
122
123 @Override
124 public long getLong(String key, long defValue) {
125 final String v = delegate.getString(key, null);
126 return v!=null ? Long.parseLong(decrypt(v)) : defValue;
127 }
128
129 @Override
130 public String getString(String key, String defValue) {
131 final String v = delegate.getString(key, null);
132 return v != null ? decrypt(v) : defValue;
133 }
134
135 @Override
136 public boolean contains(String s) {
137 return delegate.contains(s);
138 }
139
140 @Override
141 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
142 delegate.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
143 }
144
145 @Override
146 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
147 delegate.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
148 }
149
150
151
152
153 protected String encrypt( String value ) {
154
155 try {
156 final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];
157 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
158 SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
159 Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
160 pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
161 return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);
162
163 } catch( Exception e ) {
164 throw new RuntimeException(e);
165 }
166
167 }
168
169 protected String decrypt(String value){
170 try {
171 final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];
172 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
173 SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
174 Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
175 pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
176 return new String(pbeCipher.doFinal(bytes),UTF8);
177
178 } catch( Exception e) {
179 throw new RuntimeException(e);
180 }
181 }
182
183}
184
185public boolean onPreferenceChange(Preference preference, Object newValue) {
186 // get our "secure" shared preferences file.
187 SharedPreferences secure = context.getSharedPreferences(
188 "SECURE",
189 Context.MODE_PRIVATE
190 );
191 String encryptedText = null;
192 // encrypt and set the preference.
193 try {
194 encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);
195
196 Editor editor = secure.getEditor();
197 editor.putString("encryptedPassword",encryptedText);
198 editor.commit();
199 }
200 catch (Exception e) {
201 e.printStackTrace();
202 }
203 // always return false.
204 return false;
205 }