android设置存储,在android应用程序中存储用户设置的最合适方法是什么?

我同意Reto和FiXedd的观点。客观地说,在SharedPreferences中花费大量时间和精力加密密码没有多大意义,因为任何访问您的首选项文件的攻击者都很可能还可以访问应用程序的二进制文件,因此也可以对密码进行解密。

不过,话虽如此,似乎确实有一项公开倡议,即识别那些在SharedPreferences中以明文形式存储密码的移动应用程序,并对这些应用程序发出不利的光芒。看见http:/blogs.wsj.com/位数/2011/06/08/一些顶级应用程序-放置数据风险/和http://viaforensics.com/appwatchdog举几个例子。

虽然我们需要更多地关注安全问题,但我认为,在这一特定问题上的这种关注实际上并不能显著提高我们的整体安全性。然而,感知是一样的,这里有一个解决方案来加密您放置在SharedPreferences中的数据。

只需将您自己的SharedPreferences对象包装在这个对象中,您所读/写的任何数据都将自动加密和解密。例如。final SharedPreferences prefs = new ObscuredSharedPreferences(

this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE) );

// eg.    prefs.edit().putString("foo","bar").commit();prefs.getString("foo", null);

下面是这个类的代码:/**

* Warning, this gives a false sense of security.  If an attacker has enough access to

* acquire your password store, then he almost certainly has enough access to acquire your

* source binary and figure out your encryption key.  However, it will prevent casual

* investigators from acquiring passwords, and thereby may prevent undesired negative

* publicity.

*/public class ObscuredSharedPreferences implements SharedPreferences {

protected static final String UTF8 = "utf-8";

private static final char[] SEKRIT = ... ; // INSERT A RANDOM PASSWORD HERE.

// Don't use anything you wouldn't want to

// get out there if someone decompiled

// your app.

protected SharedPreferences delegate;

protected Context context;

public ObscuredSharedPreferences(Context context, SharedPreferences delegate) {

this.delegate = delegate;

this.context = context;

}

public class Editor implements SharedPreferences.Editor {

protected SharedPreferences.Editor delegate;

public Editor() {

this.delegate = ObscuredSharedPreferences.this.delegate.edit();

}

@Override

public Editor putBoolean(String key, boolean value) {

delegate.putString(key, encrypt(Boolean.toString(value)));

return this;

}

@Override

public Editor putFloat(String key, float value) {

delegate.putString(key, encrypt(Float.toString(value)));

return this;

}

@Override

public Editor putInt(String key, int value) {

delegate.putString(key, encrypt(Integer.toString(value)));

return this;

}

@Override

public Editor putLong(String key, long value) {

delegate.putString(key, encrypt(Long.toString(value)));

return this;

}

@Override

public Editor putString(String key, String value) {

delegate.putString(key, encrypt(value));

return this;

}

@Override

public void apply() {

delegate.apply();

}

@Override

public Editor clear() {

delegate.clear();

return this;

}

@Override

public boolean commit() {

return delegate.commit();

}

@Override

public Editor remove(String s) {

delegate.remove(s);

return this;

}

}

public Editor edit() {

return new Editor();

}

@Override

public Map getAll() {

throw new UnsupportedOperationException(); // left as an exercise to the reader

}

@Override

public boolean getBoolean(String key, boolean defValue) {

final String v = delegate.getString(key, null);

return v!=null ? Boolean.parseBoolean(decrypt(v)) : defValue;

}

@Override

public float getFloat(String key, float defValue) {

final String v = delegate.getString(key, null);

return v!=null ? Float.parseFloat(decrypt(v)) : defValue;

}

@Override

public int getInt(String key, int defValue) {

final String v = delegate.getString(key, null);

return v!=null ? Integer.parseInt(decrypt(v)) : defValue;

}

@Override

public long getLong(String key, long defValue) {

final String v = delegate.getString(key, null);

return v!=null ? Long.parseLong(decrypt(v)) : defValue;

}

@Override

public String getString(String key, String defValue) {

final String v = delegate.getString(key, null);

return v != null ? decrypt(v) : defValue;

}

@Override

public boolean contains(String s) {

return delegate.contains(s);

}

@Override

public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {

delegate.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);

}

@Override

public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {

delegate.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);

}

protected String encrypt( String value ) {

try {

final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));

Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");

pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),

Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));

return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);

} catch( Exception e ) {

throw new RuntimeException(e);

}

}

protected String decrypt(String value){

try {

final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));

Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");

pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),

Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));

return new String(pbeCipher.doFinal(bytes),UTF8);

} catch( Exception e) {

throw new RuntimeException(e);

}

}}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值