我的应用程序使用两个字符串作为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文件中获取它们,并将它们设置为默认字符串。我怎么能在第一时间对他们进行评价?当我使用它们解密它们时?
有什么想法吗?
感谢。
答案 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()));
}