加密我的SharedPreference

时间:2014-03-27 19:35:06

标签: android encryption sharedpreferences

我的应用程序使用两个字符串作为SharedPreferences的密码和PIN。我有文件Settings.java加载设置布局。

package org.secure.sms;

import org.krto.sms.R;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Settings extends PreferenceActivity implements   OnSharedPreferenceChangeListener {


//private static final String KEY_EDIT_TEXT_PREFERENCE = "password";


@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.layout.settings);

}


@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {
    // TODO Auto-generated method stub

}

 @Override
    protected void onStop() {
        super.onStop();
        if (!isFinishing()) {
            finish();
        }
    }

@Override
public void onBackPressed() {

    finish();
    Intent intent = new Intent(Settings.this, SecureMessagesActivity.class);
    startActivity(intent);
}   }

和settings.xml(lauout)就是上面的内容:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceCategory
        android:title="@string/password_title"
        android:key="@string/first_category">

      <EditTextPreference
            android:key="password"
            android:title="Password"
            android:summary="@string/password_define"
            android:dialogTitle="@string/pass_title"
            android:dialogMessage="@string/password_provide"   
            android:defaultValue="Default_password"
            android:inputType="textPassword" />

      </PreferenceCategory>


<PreferenceCategory
                    android:title="@string/pin_title"
                    android:key="@string/second_category">

      <EditTextPreference
                        android:key="pin"
                        android:title="PIN"
                        android:summary="@string/pin_define"
                        android:dialogTitle="@string/pin_title"
                        android:dialogMessage="@string/pin_provide"   
                        android:defaultValue="111"

                        />

      </PreferenceCategory>

<PreferenceCategory

android:title="Help"
android:layout="@layout/help"


/>

我还将带有函数的SharedPreferences字符串加载到我的应用程序中:

public String getPass(Context context)
{

    SharedPreferences prefs =   PreferenceManager.getDefaultSharedPreferences(context);

    final String PASSWORD = prefs.getString("password","DEFAULT");

    return PASSWORD;

}

如何散列或加密这两个字符串?是否有任何哈希函数或我必须加密功能?

我没有使用代码创建SharedPreferences,但是我从settings.xml文件中获取它们,并将它们设置为默认字符串。我怎么能在第一时间对他们进行评价?当我使用它们解密它们时?

有什么想法吗?

感谢。

3 个答案:

答案 0 :(得分:1)

要执行无法解密的强哈希加密,请使用SHA-256哈希函数:

MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(yourPassword.getBytes("UTF-8"));
String passwordEncrypted = Base64.encodeToString(digest.digest(), Base64.DEFAULT);

现在passwordEncrypted字符串包含yourPassword哈希值的base64表示,并且易于存储在数据库,首选项或xml文件中。

要检查密码是否输入正确,只需以相同的方式对输入进行编码,并将结果与​​存储在首选项中的哈希字符串进行比较。如果初始字符串相等,则保证哈希字符串也相等。

例如,对于&#34; Default_password&#34;结果是p1wNvKUcenG+jyIrzVNPxWuWZ5KBF8sXrHyD5CuXtbo=

答案 1 :(得分:0)

我认为加密(或者,如你所愿:哈希)动态密码并不容易。如果您的目的是在SharedPreference存储文件中存储密码的哈希值(至少),那么您需要在片段中的代码(而不是XML)中创建额外的EditTextPreference创建代码,并隐藏真实密码Preference,如下所示:

        // Remove the password from the displayed list of preference, since the password is
        // computed from clear text
        PreferenceScreen screen = getPreferenceScreen();
        Preference pref = getPreferenceManager().findPreference("password"); // <= This is the true password preference key your application is using
        screen.removePreference(pref);

        // And add a preference to the list to let the user enter the "clear text" password
        EditTextPreference password = new EditTextPreference(pref.getContext());
        password.setKey("passclear");
        password.setTitle("Password on the server");
        password.getEditText().setInputType(android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
        password.getEditText().setTransformationMethod(new PasswordTransformationMethod());
        password.setDialogTitle("Password");
        password.setSummary(getPreferenceManager().getSharedPreferences().getString("password", "").length() > 0 ? "***" : "None");
        // Update the summary dynamically so it either display "None" or a fake password
        password.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
        {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                preference.setSummary(newValue.toString().length() > 0 ? "***" : "None");
                return true;
            }
        });
        screen.addPreference(password);

然后,在您的PreferenceActivity@onDestroy处理程序中,您需要将passclear首选项的值哈希到真正的password首选项,并删除passclear首选项这样:

@Override
protected void onDestroy() {
    // Compute the hashed password here
    String password = "", stringValue = PreferenceManager.getDefaultSharedPreferences(this).getString("passclear", "");
    if (stringValue.length() > 0) {
        try {
            password = computeHash(stringValue, getSalt());
        } catch (Exception e) {
            password = "";
        }
    }

    // Remove the clear password preference
    SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
    // Save the password in the preference now
    if (password.length() > 0) editor.putString("password", password);
    // And remove the clear text so it does not appear in the xml file anymore
    editor.remove("passclear");
    editor.apply();
    super.onDestroy();
}

答案 2 :(得分:0)

我认为&#34;哈希&#34;在这种情况下,密码不是一个好的选择,因为您可能需要稍后解密它以进行某种服务器端验证。您可以在服务器端使用哈希算法。
以下是有关如何执行此操作的示例。https://www.mkyong.com/java/java-sha-hashing-example/

您可以对密码进行编码,而不是哈希,只需查看您的偏好文件即可确保它不会被盗。为此,我建议您使用Base64,因为它非常简单易用。

这是一个例子

private String encode(String normalText) {
  return new String(Base64.encodeBase64(text.getBytes()));
}

private String decode(String encodedText) {
  return new String(Base64.decodeBase64(text.getBytes()));
}