先来看看效果:
这里显示的密文就是存储在SP中的密文,下面我们再来看看sp文件内容
这样就起到了在sp存储时的加密功能,下面我们来看看代码,加密我使用的是RSA加密,并把秘钥保存在androidKeyStore中,这样就保险,更加保障了我们的秘钥安全
- 生成RSA秘钥工具类:AndroidKeyStoreRSAUtils
package tsou.com.encryption.AndroidKeyStoreRSA;
import android.content.Context;
import android.os.Build;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.support.annotation.RequiresApi;
import android.util.Log;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableEntryException;
import java.security.cert.CertificateException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import javax.crypto.Cipher;
import javax.security.auth.x500.X500Principal;
import tsou.com.encryption.aescbc.Base64Decoder;
import tsou.com.encryption.androidkeystoresign.SecurityConstants;
public class AndroidKeyStoreRSAUtils {
public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式
public static final int DEFAULT_KEY_SIZE = 2048;//秘钥默认长度
public static final byte[] DEFAULT_SPLIT = "#HUANGXIAOGUO#".getBytes(); // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密
public static final int DEFAULT_BUFFERSIZE = (DEFAULT_KEY_SIZE / 8) - 11;// 当前秘钥支持加密的最大字节数
/**
* 自己给你的别名,方便在keystore中查找秘钥
*/
public static final String SAMPLE_ALIAS = "xiaoGuoKey";
/**
* 自己给你的别名 就是SAMPLE_ALIAS
*/
private static String mAlias = null;
public static void setAlias(String alias) {
mAlias = alias;
}
/**
* 创建一个公共和私人密钥,并将其存储使用Android密钥存储库中,因此,只有
* 这个应用程序将能够访问键。
*
* @param context
* @throws InvalidAlgorithmParameterException
* @throws NoSuchProviderException
* @throws NoSuchAlgorithmException
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static KeyPair generateRSAKeyPair(Context context) throws
InvalidAlgorithmParameterException,
NoSuchProviderException, NoSuchAlgorithmException {
setAlias(SAMPLE_ALIAS);
//创建一个开始和结束时间,有效范围内的密钥对才会生成。
Calendar start = new GregorianCalendar();
Calendar end = new GregorianCalendar();
end.add(Calendar.YEAR, 1);//往后加一年
AlgorithmParameterSpec spec;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//使用别名来检索的key 。这是一个key 的key !
spec = new KeyPairGeneratorSpec.Builder(context)
//使用别名来检索的关键。这是一个关键的关键!
.setAlias(mAlias)
// 用于生成自签名证书的主题 X500Principal 接受 RFC 1779/2253的专有名词
.setSubject(new X500Principal("CN=" + mAlias))
//用于自签名证书的序列号生成的一对。
.setSerialNumber(BigInteger.valueOf(1337))
// 签名在有效日期范围内
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
} else {
//Android 6.0(或者以上)使用KeyGenparameterSpec.Builder 方式来创建,
// 允许你自定义允许的的关键属性和限制
spec = new KeyGenParameterSpec.Builder(mAlias, KeyProperties.PURPOSE_SIGN
| KeyProperties.PURPOSE_ENCRYPT
| KeyProperties.PURPOSE_DECRYPT)
.setKeySize(DEFAULT_KEY_SIZE)
.setUserAuthenticationRequired(false)
.setCertificateSubject(new X500Principal("CN=" + mAlias))
//, KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA224, KeyProperties.DIGEST_SHA384,
// KeyProperties.DIGEST_SHA512, KeyProperties.DIGEST_MD5)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1)
.setCertificateNotBefore(start.getTime())
.setCertificateNotAfter(end.getTime())
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build();
}
KeyPairGenerator kpGenerator = KeyPairGenerator
.getInstance(SecurityConstants.TYPE_RSA,
SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
kpGenerator.initialize(spec);
KeyPair kp = kpGenerator.generateKeyPair();
return kp;
}
/**
* 用公钥对字符串进行加密
*
* @param data 原文
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {
// 得到公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA);
PublicKey keyPublic = kf.generatePublic(keySpec);
// 加密数据
Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);
cp.init(Cipher.ENCRYPT_MODE, keyPublic);
return cp.doFinal(data);
}
/**
* 私钥加密
*
* @param data 待加密数据
* @param privateKey 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {
// 得到私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA);
PrivateKey keyPrivate = kf.generatePrivate(keySpec);
// 数据加密
Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, keyPrivate);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 待解密数据
* @param publicKey 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {
// 得到公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA);
PublicKey keyPublic = kf.generatePublic(keySpec);
// 数据解密
Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
cipher.init(Cipher.DECRYPT_MODE, keyPublic);
return cipher.doFinal(data);
}
/**
* 使用私钥进行解密
*/
public static byte[] decryptByPrivateKey(byte[] encrypted) throws Exception {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
if (mAlias == null) {
setAlias(SAMPLE_ALIAS);
}
//从Android加载密钥对密钥存储库中
KeyStore.Entry entry = ks.getEntry(mAlias, null);
if (entry == null) {
return null;
}
if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
return null;
}
PrivateKey keyPrivate = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
// 解密数据
Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);
cp.init(Cipher.DECRYPT_MODE, keyPrivate);
byte[] arr = cp.doFinal(encrypted);
return arr;
}
/**
* 用公钥对字符串进行分段加密
*/
public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception {
int dataLen = data.length;
if (dataLen <= DEFAULT_BUFFERSIZE) {
return encryptByPublicKey(data, publicKey);
}
List<Byte> allBytes = new ArrayList<Byte>(2048);
int bufIndex = 0;
int subDataLoop = 0;
byte[] buf = new byte[DEFAULT_BUFFERSIZE];
for (int i = 0; i < dataLen; i++) {
buf[bufIndex] = data[i];
if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {
subDataLoop++;
if (subDataLoop != 1) {
for (byte b : DEFAULT_SPLIT) {
allBytes.add(b);
}
}
byte[] encryptBytes = encryptByPublicKey(buf, publicKey);
for (byte b : encryptBytes) {
allBytes.add(b);
}
bufIndex = 0;
if (i == dataLen - 1) {
buf = null;
} else {
buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];
}
}
}
byte[] bytes = new byte[allBytes.size()];
{
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b.byteValue();
}
}
return bytes;
}
/**
* 分段加密
*
* @param data 要加密的原始数据
* @param privateKey 秘钥
*/
public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception {
int dataLen = data.length;
if (dataLen <= DEFAULT_BUFFERSIZE) {
return encryptByPrivateKey(data, privateKey);
}
List<Byte> allBytes = new ArrayList<Byte>(2048);
int bufIndex = 0;
int subDataLoop = 0;
byte[] buf = new byte[DEFAULT_BUFFERSIZE];
for (int i = 0; i < dataLen; i++) {
buf[bufIndex] = data[i];
if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {
subDataLoop++;
if (subDataLoop != 1) {
for (byte b : DEFAULT_SPLIT) {
allBytes.add(b);
}
}
byte[] encryptBytes = encryptByPrivateKey(buf, privateKey);
for (byte b : encryptBytes) {
allBytes.add(b);
}
bufIndex = 0;
if (i == dataLen - 1) {
buf = null;
} else {
buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];
}
}
}
byte[] bytes = new byte[allBytes.size()];
{
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b.byteValue();
}
}
return bytes;
}
/**
* 公钥分段解密
*
* @param encrypted 待解密数据
* @param publicKey 密钥
*/
public static byte[] decryptByPublicKeyForSpilt(byte[] encrypted, byte[] publicKey) throws Exception {
int splitLen = DEFAULT_SPLIT.length;
if (splitLen <= 0) {
return decryptByPublicKey(encrypted, publicKey);
}
int dataLen = encrypted.length;
List<Byte> allBytes = new ArrayList<Byte>(1024);
int latestStartIndex = 0;
for (int i = 0; i < dataLen; i++) {
byte bt = encrypted[i];
boolean isMatchSplit = false;
if (i == dataLen - 1) {
// 到data的最后了
byte[] part = new byte[dataLen - latestStartIndex];
System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);
byte[] decryptPart = decryptByPublicKey(part, publicKey);
for (byte b : decryptPart) {
allBytes.add(b);
}
latestStartIndex = i + splitLen;
i = latestStartIndex - 1;
} else if (bt == DEFAULT_SPLIT[0]) {
// 这个是以split[0]开头
if (splitLen > 1) {
if (i + splitLen < dataLen) {
// 没有超出data的范围
for (int j = 1; j < splitLen; j++) {
if (DEFAULT_SPLIT[j] != encrypted[i + j]) {
break;
}
if (j == splitLen - 1) {
// 验证到split的最后一位,都没有break,则表明已经确认是split段
isMatchSplit = true;
}
}
}
} else {
// split只有一位,则已经匹配了
isMatchSplit = true;
}
}
if (isMatchSplit) {
byte[] part = new byte[i - latestStartIndex];
System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);
byte[] decryptPart = decryptByPublicKey(part, publicKey);
for (byte b : decryptPart) {
allBytes.add(b);
}
latestStartIndex = i + splitLen;
i = latestStartIndex - 1;
}
}
byte[] bytes = new byte[allBytes.size()];
{
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b.byteValue();
}
}
return bytes;
}
/**
* 使用私钥分段解密
*/
public static byte[] decryptByPrivateKeyForSpilt(byte[] encrypted) throws Exception {
int splitLen = DEFAULT_SPLIT.length;
if (splitLen <= 0) {
return decryptByPrivateKey(encrypted);
}
int dataLen = encrypted.length;
List<Byte> allBytes = new ArrayList<Byte>(1024);
int latestStartIndex = 0;
for (int i = 0; i < dataLen; i++) {
byte bt = encrypted[i];
boolean isMatchSplit = false;
if (i == dataLen - 1) {
// 到data的最后了
byte[] part = new byte[dataLen - latestStartIndex];
System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);
byte[] decryptPart = decryptByPrivateKey(part);
for (byte b : decryptPart) {
allBytes.add(b);
}
latestStartIndex = i + splitLen;
i = latestStartIndex - 1;
} else if (bt == DEFAULT_SPLIT[0]) {
// 这个是以split[0]开头
if (splitLen > 1) {
if (i + splitLen < dataLen) {
// 没有超出data的范围
for (int j = 1; j < splitLen; j++) {
if (DEFAULT_SPLIT[j] != encrypted[i + j]) {
break;
}
if (j == splitLen - 1) {
// 验证到split的最后一位,都没有break,则表明已经确认是split段
isMatchSplit = true;
}
}
}
} else {
// split只有一位,则已经匹配了
isMatchSplit = true;
}
}
if (isMatchSplit) {
byte[] part = new byte[i - latestStartIndex];
System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);
byte[] decryptPart = decryptByPrivateKey(part);
for (byte b : decryptPart) {
allBytes.add(b);
}
latestStartIndex = i + splitLen;
i = latestStartIndex - 1;
}
}
byte[] bytes = new byte[allBytes.size()];
{
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b.byteValue();
}
}
return bytes;
}
/**
* 通过字符串生成私钥,转换服务器传递过来的私钥
*/
public static PrivateKey getPrivateKey(String privateKeyData) {
PrivateKey privateKey = null;
try {
byte[] decodeKey = Base64Decoder.decodeToBytes(privateKeyData);
PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//创建x509证书封装类
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA
privateKey = keyFactory.generatePrivate(x509);//生成私钥
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
/**
* 通过字符串生成公钥,转换服务器传递过来的公钥
*/
public static PublicKey getPublicKey(String publicKeyData) {
PublicKey publicKey = null;
try {
byte[] decodeKey = Base64Decoder.decodeToBytes(publicKeyData);
X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(x509);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
/**
* 判断是否创建过秘钥
*
* @return
* @throws KeyStoreException
* @throws CertificateException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws UnrecoverableEntryException
*/
public static boolean isHaveKeyStore() {
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
if (mAlias == null) {
setAlias(SAMPLE_ALIAS);
}
//从Android加载密钥对密钥存储库中
KeyStore.Entry entry = ks.getEntry(mAlias, null);
if (entry == null) {
return false;
}
} catch (KeyStoreException e) {
e.printStackTrace();
return false;
} catch (CertificateException e) {
e.printStackTrace();
return false;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 获得本地AndroidKeyStore中的公钥
*
* @return
*/
public static PublicKey getLocalPublicKey() {
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
if (mAlias == null) {
setAlias(SAMPLE_ALIAS);
}
//从Android加载密钥对密钥存储库中
KeyStore.Entry entry = ks.getEntry(mAlias, null);
if (entry == null) {
return null;
}
if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
return null;
}
PublicKey publicKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey();
return publicKey;
} catch (KeyStoreException e) {
e.printStackTrace();
return null;
} catch (CertificateException e) {
e.printStackTrace();
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
return null;
}
}
}
package tsou.com.encryption.androidkeystoresign;
public class SecurityConstants {
public static final String KEYSTORE_PROVIDER_ANDROID_KEYSTORE = "AndroidKeyStore";
public static final String TYPE_RSA = "RSA";
public static final String TYPE_DSA = "DSA";
public static final String TYPE_BKS = "BKS";
public static final String SIGNATURE_SHA256withRSA = "SHA256withRSA";
public static final String SIGNATURE_SHA512withRSA = "SHA512withRSA";
}
- 加密封装在SPSecuredUtils秘钥中方便拿过来直接用
package tsou.com.encryption.sp;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.interfaces.RSAPublicKey;
import java.util.Map;
import tsou.com.encryption.AndroidKeyStoreRSA.AndroidKeyStoreRSAUtils;
import tsou.com.encryption.aescbc.Base64Decoder;
import tsou.com.encryption.aescbc.Base64Encoder;
/**
* Created by zb666 on 2017/2/9.
*/
public class SPSecuredUtils {
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "sp_secured";
private static SharedPreferences mSharedPreferences;
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
* @param publicKey
*/
public static void put(Context context, String key, Object object, RSAPublicKey publicKey) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
// byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKeyForSpilt(encryptionString.getBytes(),
// publicKey.getEncoded());
try {
if (object instanceof String) {
byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKey(((String) object).getBytes(),
publicKey.getEncoded());
editor.putString(key, Base64Encoder.encode(encryptBytes));
} else if (object instanceof Integer) {
put(context, key, Integer.toString((Integer) object), publicKey);
} else if (object instanceof Boolean) {
put(context, key, Boolean.toString((Boolean) object), publicKey);
} else if (object instanceof Float) {
put(context, key, Float.toString((Float) object), publicKey);
} else if (object instanceof Long) {
put(context, key, Long.toString((Long) object), publicKey);
} else {
put(context, key, object.toString(), publicKey);
}
SharedPreferencesCompat.apply(editor);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
// byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKeyForSpilt(
// Base64Decoder.decodeToBytes(decodeString));
try {
if (defaultObject instanceof String) {
String string = sp.getString(key, (String) defaultObject);
if (!string.equals((String) defaultObject)) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return new String(decryptBytes);
}
return (String) defaultObject;
} else if (defaultObject instanceof Integer) {
String string = sp.getString(key, Integer.toString((Integer) defaultObject));
if (!string.equals(Integer.toString((Integer) defaultObject))) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return Integer.valueOf(new String(decryptBytes));
}
return (Integer) defaultObject;
} else if (defaultObject instanceof Boolean) {
String string = sp.getString(key, Boolean.toString((Boolean) defaultObject));
if (!string.equals(Boolean.toString((Boolean) defaultObject))) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return Boolean.valueOf(new String(decryptBytes));
}
return (Boolean) defaultObject;
} else if (defaultObject instanceof Float) {
String string = sp.getString(key, Float.toString((Float) defaultObject));
if (!string.equals(Float.toString((Float) defaultObject))) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return Float.valueOf(new String(decryptBytes));
}
return (Float) defaultObject;
} else if (defaultObject instanceof Long) {
String string = sp.getString(key, Long.toString((Long) defaultObject));
if (!string.equals(Long.toString((Long) defaultObject))) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return Long.valueOf(new String(decryptBytes));
}
return (Long) defaultObject;
}else if (defaultObject instanceof Double){
String string = sp.getString(key, Double.toString((Double) defaultObject));
if (!string.equals(Double.toString((Double) defaultObject))) {
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(string));
return Double.valueOf(new String(decryptBytes));
}
return (Double) defaultObject;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将对象储存到sharepreference
*
* @param key
* @param device
* @param <T>
*/
public static <T> boolean saveDeviceData(Context context, String key, T device, RSAPublicKey publicKey) {
if (mSharedPreferences == null) {
mSharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try { //Device为自定义类
// 创建对象输出流,并封装字节流
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 将对象写入字节流
oos.writeObject(device);
// 将字节流编码成base64的字符串
String oAuth_Base64 = new String(Base64.encode
(baos.toByteArray(), Base64.DEFAULT));
byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKey(oAuth_Base64.getBytes(),
publicKey.getEncoded());
mSharedPreferences.edit().putString(key, Base64Encoder.encode(encryptBytes)).apply();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将对象从shareprerence中取出来
*
* @param key
* @param <T>
* @return
*/
public static <T> T getDeviceData(Context context, String key) {
if (mSharedPreferences == null) {
mSharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
}
try {
T device = null;
String productBase64 = mSharedPreferences.getString(key, null);
if (productBase64 == null) {
return null;
}
byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey(
Base64Decoder.decodeToBytes(productBase64));
// 读取字节
byte[] base64 = Base64.decode(new String(decryptBytes).getBytes(), Base64.DEFAULT);
// 封装到字节流
ByteArrayInputStream bais = new ByteArrayInputStream(base64);
// 再次封装
ObjectInputStream bis = new ObjectInputStream(bais);
// 读取对象
device = (T) bis.readObject();
return device;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 移除某个key值已经对应的值
*
* @param context
* @param key
*/
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*
* @param context
*/
public static void clear(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*
* @param context
* @param key
* @return
*/
public static boolean contains(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @param context
* @return
*/
public static Map<String, ?> getAll(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
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();
}
}
}
- 执行操作
package tsou.com.encryption.activity.SP;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.interfaces.RSAPublicKey;
import tsou.com.encryption.AndroidKeyStoreRSA.AndroidKeyStoreRSAUtils;
import tsou.com.encryption.R;
import tsou.com.encryption.aescbc.Base64Encoder;
import tsou.com.encryption.sp.SPSecuredUtils;
public class SPActivity extends AppCompatActivity implements View.OnClickListener {
private EditText encryptionContext;
private Button encryption;
private TextView tvEncryption;
private Button decode;
private TextView tvDecode;
private Activity mActivity;
private Context mContext;
private RSAPublicKey publicKey;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aes);
mActivity = this;
mContext = this;
encryptionContext = (EditText) findViewById(R.id.et_encryption_context);
encryption = (Button) findViewById(R.id.btn_encryption);
tvEncryption = (TextView) findViewById(R.id.tv_encryption);
decode = (Button) findViewById(R.id.btn_decode);
tvDecode = (TextView) findViewById(R.id.tv_decode);
encryption.setText("存入");
decode.setText("读取");
initListener();
}
private void initListener() {
encryption.setOnClickListener(this);
decode.setOnClickListener(this);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (AndroidKeyStoreRSAUtils.isHaveKeyStore()) {//是否有秘钥
publicKey = (RSAPublicKey) AndroidKeyStoreRSAUtils.getLocalPublicKey();
if (publicKey != null) {
Toast.makeText(mContext, "已经生成过密钥对", Toast.LENGTH_SHORT).show();
return;
}
}
try {//在项目中放在application或启动页中
KeyPair keyPair = AndroidKeyStoreRSAUtils.generateRSAKeyPair(mContext);
// 公钥
publicKey = (RSAPublicKey) keyPair.getPublic();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_encryption://加密
String encryptionString = encryptionContext.getText().toString().trim();
if (TextUtils.isEmpty(encryptionString)) {
Toast.makeText(mContext, "请输入加密内容", Toast.LENGTH_SHORT).show();
return;
}
SPSecuredUtils.put(mContext, "huangxiaoguo", encryptionString, publicKey);
// SPSecuredUtils.put(mContext, "huangxiaoguo", 1, publicKey);
// SPSecuredUtils.put(mContext, "huangxiaoguo", 0.01, publicKey);
// SPSecuredUtils.put(mContext, "huangxiaoguo", true, publicKey);
/**
* 下面是显示用的
*/
try {
byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKey(encryptionString.getBytes(),
publicKey.getEncoded());
String encryStr = Base64Encoder.encode(encryptBytes);
tvEncryption.setText(encryStr);
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.btn_decode://解密
String decodeString = tvEncryption.getText().toString().trim();
if (TextUtils.isEmpty(decodeString)) {
Toast.makeText(mContext, "请先加密", Toast.LENGTH_SHORT).show();
return;
}
String huangxiaoguo = (String) SPSecuredUtils.get(mContext, "huangxiaoguo", "");
// int huangxiaoguo = (int) SPSecuredUtils.get(mContext, "huangxiaoguo", 0);
// double huangxiaoguo = (double) SPSecuredUtils.get(mContext, "huangxiaoguo", 0.0);
// boolean huangxiaoguo = (boolean) SPSecuredUtils.get(mContext, "huangxiaoguo",false);
tvDecode.setText(huangxiaoguo+"");
break;
}
}
}
这样就实现了sp中对数据的加密………..
更多加密方式DEMO请查看:https://gitee.com/huangxiaoguo/androidGeZhongJiaMiZongJie
更多加密方式博文请查看:http://blog.csdn.net/huangxiaoguo1/article/details/78043354