/**
* SharedPreferences 储存, key加密储存,value加密储存
*
* @author gb 2017/9/7.
*/
public class SPUtils {
/**
* 保存在手机里面的文件名
*/
private static final String FILE_NAME = "jump";
private static final int MODE = Context.MODE_PRIVATE;
private static Context mContext;
private SPUtils() {
throw new RuntimeException("SPUtils cannot be initialized!");
}
public static void init(Context context) {
mContext = context;
}
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param key
* @param value
*/
public static void put(String key, String value) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
SharedPreferences.Editor editor = sp.edit();
String encryptKey = encryptKey(key);
String encryptValue = "";
try {
encryptValue = SPUtilsAES.encrypt(value);//加密结果
} catch (Exception e) {
LogUtils.d(e.toString());
encryptValue = value;
}
LogUtils.d("sp.put加密结果key:" + key + ",加密后结果key:" + encryptKey);
LogUtils.d("sp.put加密结果value:" + value + ",加密后结果value:" + encryptValue);
editor.putString(encryptKey, encryptValue);
SharedPreferencesCompat.apply(editor);
}
/**
* 保存数据
*
* @param list
* @return
*/
public static boolean putArray(List list) {
SharedPreferences sp = mContext.getSharedPreferences(SPConstant.SP_TABLE_NAME, MODE);
SharedPreferences.Editor edit = sp.edit();
edit.putInt("Status_size", list.size());
for (int i = 0; i < list.size(); i++) {
edit.remove("Status_" + i);
edit.putString("Status_" + i, list.get(i));
}
return edit.commit();
}
/**
* 取出数据
*
* @return
*/
public static List getArray() {
List list = new ArrayList<>();
SharedPreferences sp = mContext.getSharedPreferences(SPConstant.SP_TABLE_NAME, MODE);
int size = sp.getInt("Status_size", 0);
for (int i = 0; i < size; i++) {
list.add(sp.getString("Status_" + i, null));
}
return list;
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param key
* @param defaultValue
* @return
*/
public static String get(String key, String defaultValue) {
defaultValue = (defaultValue == null) ? "" : defaultValue;
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
String encryptKey = encryptKey(key);
String decryString = sp.getString(encryptKey, defaultValue);
// 调用AES解密方法
try {
if (!defaultValue.equalsIgnoreCase(decryString)) {
decryString = SPUtilsAES.decrypt(decryString);
} else {
decryString = defaultValue;
}
} catch (Exception e) {
LogUtils.d(e.toString());
decryString = defaultValue;
}
LogUtils.d("sp.get()key=" + key + "解密结果:" + decryString);
return decryString;
}
/**
* 移除某个key值已经对应的值
*
* @param key
*/
public static void remove(String key) {
key = encryptKey(key);
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*/
public static void clear() {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*
* @param key
* @return
*/
public static boolean contains(String key) {
key = encryptKey(key);
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @return
*/
public static Map getAll() {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, MODE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*
* @author zhy
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
editor.commit();
}
}
/**
* sp的key 加密
*
* @param key
* @return encryptKey
*/
private static String encryptKey(String key) {
String encryptKey = "";
try {
encryptKey = SPUtilsAES.encrypt(key);//加密结果
} catch (Exception e) {
LogUtils.d(e.toString());
encryptKey = key;
}
return encryptKey;
}
}
加密如下:
/**
* SPUtilsAES.加密
*/
public class SPUtilsAES {
public static final String masterPassword = "jump"; // 设置加密密匙
// public static void main(String[] args) throws Exception {
// // 设置加密密匙
// String masterPassword = "sad sad 说";
// // 设置原文
// String originalText = "微信啊显示";
// // 调用AES加密方法
// String encryptingCode = encrypt(originalText);
// System.out.println("加密结果:" + encryptingCode);
// // 调用AES解密方法
// String decryString = decrypt(encryptingCode);
// System.out.println("解密结果:" + decryString);
// }
// AES加密
// encryptText为要加密的内容
// seed为密匙
public static String encrypt(String encryptText)
throws Exception {
byte[] rawKey = getRawKey(masterPassword.getBytes());
byte[] result = encrypt(rawKey, encryptText.getBytes());
return toHex(result);
}
/**
* AES解密
* decryptText为需要解密的内容
* seed为密匙
*
* @param decryptText
* @return
* @throws Exception
*/
public static String decrypt(String decryptText)
throws Exception {
byte[] rawKey = getRawKey(masterPassword.getBytes());
byte[] enc = toByte(decryptText);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
// 加密
private static byte[] encrypt(byte[] raw, byte[] bytes) throws Exception {
// 生成一组扩展密匙,并放入一个数组之中
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
// 用ENCRYPT_MODE模式,用skeySpec密码组,生成AES加密方法
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
// 得到加密数据
byte[] encrypted = cipher.doFinal(bytes);
return encrypted;
}
// 解密
private static byte[] decrypt(byte[] rawKey, byte[] enc) throws Exception {
// 生成一组扩展密匙,并放入一个数组之中
SecretKeySpec skeyKeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
// 用DECRYPT_MODE模式,用skeySpec密码组,生成AES解密方法
cipher.init(Cipher.DECRYPT_MODE, skeyKeySpec);
// 得到解密数据
byte[] decrypted = cipher.doFinal(enc);
return decrypted;
}
// 对密匙进行编码
private static byte[] getRawKey(byte[] bytes) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
//SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");==》 改成
// SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
sr.setSeed(bytes);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
/**
* 7.0的手机版本,加密报错
*/
public static class CryptoProvider extends Provider {
/**
* Creates a Provider and puts parameters
*/
public CryptoProvider() {
super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
put("SecureRandom.SHA1PRNG",
"org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
}
}
// 将十六进制字符串为十进制字符串
private static String fromHex(String hex) {
return new String(toByte(hex));
}
// 将十六进制字符串为十进制字节数组
private static byte[] toByte(String hex) {
int len = hex.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = Integer.valueOf(hex.substring(2 * i, 2 * i + 2), 16)
.byteValue();
}
return result;
}
// 把一个十进制字节数组转换成十六进制
private static String toHex(String txt) {
return toHex(txt.getBytes());
}
// 把一个十进制字节数组转换成十六进制
private 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 result, byte b) {
result.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0X0f));
}
}