我正在创建一个使用用户名/密码连接到服务器的应用程序,我想启用“保存密码”选项,这样用户就不必在每次应用程序启动时输入密码。

我试图用共享偏好来做,但不确定这是否是最好的解决方案。

我很感激任何关于如何在Android应用程序中存储用户值/设置的建议。


当前回答

正如其他人已经指出的,你可以使用SharedPreferences一般,但如果你想存储加密的数据有点不方便。幸运的是,现在有一种更简单、更快速的方法来加密数据,因为有一个SharedPreferences的实现可以加密密钥和值。你可以在Android JetPack Security中使用EncryptedSharedPreferences。

只需在build.gradle中添加AndroidX Security:

implementation 'androidx.security:security-crypto:1.0.0-rc01'

你可以这样使用它:

String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    "secret_shared_prefs",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

// use the shared preferences and editor as you normally would
SharedPreferences.Editor editor = sharedPreferences.edit();

详情请访问:https://android-developers.googleblog.com/2020/02/data-encryption-on-android-with-jetpack.html

官方文档:https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

其他回答

使用Richard提供的代码片段,您可以在保存密码之前对其进行加密。然而,首选项API并没有提供一种简单的方法来拦截值并加密它-你可以通过OnPreferenceChange监听器阻止它被保存,理论上你可以通过preferenceChangeListener修改它,但这会导致一个无休止的循环。

我之前建议添加一个“隐藏的”首选项来完成这个任务。这绝对不是最好的方法。我将提出另外两个我认为更可行的选择。

首先,最简单的,是在preferenceChangeListener中,你可以抓取输入的值,加密,然后保存到另一个首选项文件中:

  public boolean onPreferenceChange(Preference preference, Object newValue) {
      // get our "secure" shared preferences file.
      SharedPreferences secure = context.getSharedPreferences(
         "SECURE",
         Context.MODE_PRIVATE
      );
      String encryptedText = null;
      // encrypt and set the preference.
      try {
         encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);

         Editor editor = secure.getEditor();
         editor.putString("encryptedPassword",encryptedText);
         editor.commit();
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      // always return false.
      return false; 
   }

第二种方法,也是我现在更喜欢的方法,是创建自己的自定义首选项,扩展EditTextPreference, @Override setText()和getText()方法,以便setText()加密密码,getText()返回null。

首先,我认为用户的数据不应该存储在手机上,如果必须将数据存储在手机上的某个地方,它应该在应用程序的私有数据中加密。用户凭证的安全性应该是应用程序的优先级。

敏感数据必须安全存储,否则就不存储。在设备丢失或恶意软件感染的情况下,不安全存储的数据可能会受到损害。

您需要使用sqlite,安全工具来存储密码。 下面是最好的例子,它存储密码——passwordsafe。 这是来源和解释的链接 http://code.google.com/p/android-passwordsafe/

您还可以查看这个小库,其中包含您提到的功能。

https://github.com/kovmarci86/android-secure-preferences

它与这里的其他一些方法类似。希望会有所帮助:)

我就是这么做的。

这不会在严格模式下给出错误。

public class UserPreferenceUtil
{

    private static final String  THEME = "THEME";
    private static final String  LANGUAGE = "LANGUAGE";

    public static String getLanguagePreference(Context context)
    {

        String lang = getPreferenceByKey(context,LANGUAGE);

        if( lang==null || "System".equalsIgnoreCase(lang))
        {
            return null;
        }


        return lang;
    }

    public static void saveLanguagePreference(Context context,String value)
    {
        savePreferenceKeyValue(context, LANGUAGE,value);
    }

    public static String getThemePreference(Context context)
    {

        return getPreferenceByKey(context,THEME);
    }

    public static void saveThemePreference(Context context, String value)
    {
        savePreferenceKeyValue(context,THEME,value);

    }

    public static String getPreferenceByKey(Context context, String preferenceKey )
    {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

        String value = sharedPreferences.getString(preferenceKey, null);

        return value;
    }

    private static void savePreferenceKeyValue(Context context, String preferenceKey, String value)
    {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(preferenceKey,value);
        editor.apply();

    }


}

我的应用程序不需要密码。但是,我不会保存密码或加密密码,而是保存单向散列。当用户登录时,我将以同样的方式哈希输入,并将其与存储的哈希匹配。