使用AES加密进行Android的SharedPreferences存储

1.概述
SharedPreferences是Android提供用来存储一些简单配置信息的机制,其以KEY-VALUE对的方式进行存储,以便我们可以方便进行读取和存储。主要可以用来存储应用程序的欢迎语、常量参数或登录账号密码等。
2.实例
(1)创建项目SharedPreferencesDemo项目

(2)编辑主界面的布局文件main.xml如下:

[xhtml] view plain copy

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SharedPreferences,是Android提供用来存储一些简单的配置信息的一种机制。"
/>
<EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtAccount" android:text=""></EditText>
<EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtPassword" android:text=""></EditText>
<Button android:text="清空" android:id="@+id/btnClear" android:layout_width="fill_parent" android:layout_height="wrap_content"> </Button>
<Button android:text="退出" android:id="@+id/btnExit" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
</LinearLayout>

(3)创建AES加解密工具类AESEncryptor.java
其中主要提供加密encrypt、解密decrypt两个方法。(AES加解密算法具体大家可以到网上搜索相关资料)
以下为该类文件的源码:
[java] view plain copy

package ni.demo.sharedpreferences;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* AES加密器
* @author Eric_Ni
*
*/
public class AESEncryptor {
/**
* AES加密
*/
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}

/**
* AES解密
*/
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}

private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}

private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}

public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}

public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}

public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}

(4)编辑SharedPreferencesDemo.java
源码如下:
[java] view plain copy

package ni.demo.sharedpreferences;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class SharedPreferencesDemo extends Activity {
public static final String MY_PREFERENCES = "MY_PREFERENCES"; //Preferences文件的名称
public static final String MY_ACCOUNT = "MY_ACCOUNT"; //
public static final String MY_PASSWORD = "MY_PASSWORD";

private EditText edtAccount;
private EditText edtPassword;
private Button btnClear;
private Button btnExit;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

edtAccount = (EditText)findViewById(R.id.edtAccount);
edtPassword = (EditText)findViewById(R.id.edtPassword);
//获取名字为“MY_PREFERENCES”的参数文件对象,并获得MYACCOUNT、MY_PASSWORD元素的值。
SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);
String account = sp.getString(MY_ACCOUNT, "");
String password = sp.getString(MY_PASSWORD, "");
//对密码进行AES解密
try{
password = AESEncryptor.decrypt("41227677", password);
}catch(Exception ex){
Toast.makeText(this, "获取密码时产生解密错误!", Toast.LENGTH_SHORT);
password = "";
}
//将账号和密码显示在EditText控件上。
edtAccount.setText(account);
edtPassword.setText(password);

//获取"清空"按钮的对象,并为其绑定监听器,如被点击则清空账号和密码控件的值。
btnClear = (Button)findViewById(R.id.btnClear);
btnClear.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
edtAccount.setText("");
edtPassword.setText("");
}
});
//获取“退出”按钮的对象,并为其绑定监听,如被点击则退出程序。
btnExit = (Button)findViewById(R.id.btnExit);
btnExit.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
SharedPreferencesDemo.this.finish();
}
});
}
@Override
protected void onStop() {
super.onStop();
//获得账号、密码控件的值,并使用AES加密算法给密码加密。
String account = edtAccount.getText().toString();
String password = edtPassword.getText().toString();
try{
password = AESEncryptor.encrypt("41227677", password);
}catch(Exception ex){
Toast.makeText(this, "给密码加密时产生错误!", Toast.LENGTH_SHORT);
password = "";
}
//获取名字为“MY_PREFERENCES”的参数文件对象。
SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);
//使用Editor接口修改SharedPreferences中的值并提交。
Editor editor = sp.edit();
editor.putString(MY_ACCOUNT, account);
editor.putString(MY_PASSWORD,password);
editor.commit();
}

}

(5)效果测试
首先,在AVD我们可以看到如下界面,在两个控件上我们分别输入abc和123456。
使用AES加密进行Android的SharedPreferences存储

接着,我们打开DDMS的File Explore可以看到在data->data->ni->shared_prefs下面产生了一个名字叫做MY_PREFERENCES.xml的文件,该文件就是用来存储我们刚才设置的账号和密码。
将其导出,并打开,可以看到如下内容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="MY_ACCOUNT">abc</string>
<string name="MY_PASSWORD">04B75FAD36E907BE50CE3222B0052B79</string>
</map>
这说明我们可以成功将账号和加密后的密码保存下来了。
最后,我们点击“退出”按钮将应用程序结束掉,再重新打开。我们又再次看到我们退出前的界面,账号密码已经被重新读取出来。

文章的最后,我们进入Android API手册,看看关于SharedPreferences的介绍:
Interface for accessing and modifying preference data returned by getSharedPreferences(String, int). For any particular set of preferences, there is a single instance of this class that all clients share. Modifications to the preferences must go through an SharedPreferences.Editor object to ensure the preference values remain in a consistent state and control when they are committed to storage.

SharedPreferences是一个用来访问和修改选项数据的接口,通过getSharedPreferences(Stirng,int)来获得该接口。对于任何特别的选项集,只能有一个实例供所有客户端共享。针对选项参数的修改必须通过一个SharedPreferences.Editor对象来进行,以保证所有的选项值保持在一个始终如一的状态,并且通过该对象提交存储。

可见,SharedPreferences操作选项文件时是线程安全的。

分类:默认分类 时间:2012-01-05 人气:11
本文关键词:
分享到:

相关文章

  • Android-SharedPreferences源码学习与最佳实践 2012-07-02

    最近有个任务是要做应用启动时间优化,然后记录系统启动的各个步骤所占用的时间,发现有一个方法是操作SharedPreferences的,里面仅仅是读了2个key,然后更新一下值,然后再写回去,耗时竟然在500ms以上(应用初次安装的时候),感到非常吃惊。以前只是隐约的知道SharedPreferences是跟硬盘上的一个xml文件对应的,具体的实现还真没研究过,下面我们就来看看SharedPreferences到底是个什么玩意,为什么效率会这么低? SharedPreferences是存放在Con

  • Android--配置文件的保存SharedPreferences进行数据存储 2013-04-04

    很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件或者xml进行保存。如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferen

  • Android数据存储方式之SharedPreference 2012-01-24

    除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:   一、根据Context获取SharedPreferences对象

  • Android数据的四种存储方式之SharedPreferences 2013-12-05

      除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:   一、根据Context获取SharedPreferences对象   二、利用e

  • Android开发--SharedPreferences初步介绍 2014-04-12

    存储数据在Android开发中是一项非常重要的功能,下面介绍的这种技术是利用XML文件存储键值对。 SharedPreferences的使用主要有四步: 1)获得SharedPreferences对象 2)获得SharedPrefercences.Editor对象 3)使用putXXX方法保存数据 4)将数据保存在文件中 下面的这个例子利用SharedPreferences实现存储简单的数据,储存的内容为test.xml,文件中的内容如下 [html] www.2cto.com <?xml

  • Android数据储存--SharedPreferences储存 2014-12-05

    SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data//shared_prefs目录下。 读取SharedPreference 1.获取SharedPreference对象 /* * name 打开的SharedPreferences文件名称(不需要.xml后缀) * mode 打开的SharedPreferences模式 */ SharedPreferences

  • Android存储之SharedPreferences 2014-12-15

    SharedPreferences是Android提供用来存储一些简单的配置信息的一种机制,例如,一些默认欢迎语、登录的用户名和密码等。其以键值对的方式存储,使得我们可以很方便的读取和存入,下面看一个演示的例子。 实例:SharedPreferencesDemo 代码逻辑: 应用启动时尝试从SharedPreferences中读取保存的用户名和用户密码,并将结果显示在UI界面相应的编辑框中。 单击登录按钮,如果用户名和用户密码编辑框不为空,则将编辑框中输入的用户名和密码保存到SharedPref

  • [Android] 数据实体的自动存取--SharedPreferences篇 2012-03-12

    本例代码以SharedPreferences为数据存取载体。 利用SharedPreferences存取一个数据,步骤如下: [java] SharedPreferences sharedPre = getSharedPreferences(name, mode); 存: SharedPreferences.Editor editor = sharedPre.edit(); editor.put(key,value); editor.commit(); 取: value = sharedPre.

  • Android ART 的初始化和启动 2012-04-08

    ART的初始化 下面我们从JNI_GetDefaultJavaVMInitArgs(),JNI_CreateJavaVM()和JNI_GetCreatedJavaVMs()三个函数入手来了解ART的初始化过程。这三个函数的代码位于jni_internal.cc中。 JNI_GetDefaultJavaVMInitArgs()函数在ART中没有作为,只是返回JNI_ERR。如下所示: extern "C" jintJNI_GetDefaultJavaVMInitArgs(void* ) { ret

Copyright (C) quwantang.com, All Rights Reserved.

趣玩堂 版权所有 京ICP备15002868号

processed in 0.065 (s). 10 q(s)