android 非对称加密,Android KeyStore 非对称加密存储
记录使用KeyStore的公钥和私钥进行数据加密,使用SharedPreferences进行存储背景在业务中,我们可能需要面对在 Android 本地存储用户 token、用户信息等敏感数据进行加密。本文将讲述一种安全系数较高的Android本地存储方案。思路整个方案的核心思路围绕 KeyStore 展开,如果不太了解 KeyStore 的小伙伴,请先阅读Android 密钥库系统。由于 KeyS
记录使用KeyStore的公钥和私钥进行数据加密,使用SharedPreferences进行存储
背景
在业务中,我们可能需要面对在 Android 本地存储用户 token、用户信息等敏感数据进行加密。本文将讲述一种安全系数较高的Android本地存储方案。
思路
整个方案的核心思路围绕 KeyStore 展开,如果不太了解 KeyStore 的小伙伴,请先阅读Android 密钥库系统。
由于 KeyStore 在 Android 6.0 前后差异较大,并且 Android 4.3 以下系统并不支持 KeyStore,方案需要根据不同的 Android 版本做不同的处理,以及需要提供降级方案。加解密算法采用 RSA/ECB/PKCS1Padding。
Android6.0及以上版本
这种情况下方案最简单,随机生成2048位RSA key和iv,key存储在KeyStore中,设置alias,iv存储在SharedPreferences中。需要加解密的时候通过alias从KeyStore中取key,从SharedPreferences中取iv。
1.首先初始化KeyStore
private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
private static final String RSA = "RSA";
try {
mKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
mKeyStore.load(null);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
2.然后就是生成key了
try {
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setCertificateSubject(new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"))
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setKeySize(2048)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.setRandomizedEncryptionRequired(false)
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE);
generator.initialize(spec);
generator.generateKeyPair();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
Android 4.3 - 5.1
算法采用 RSA/ECB/PKCS1Padding,随机生成2048位RSA key和iv,key存储在KeyStore中,设置alias,iv存储在SharedPreferences中。需要加解密的时候通过alias从KeyStore中取key,从SharedPreferences中取iv。
Calendar endDate = Calendar.getInstance();
endDate.add(Calendar.YEAR, 10);
try {
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(mContext.getApplicationContext())
.setAlias(alias)
.setSubject(new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(Calendar.getInstance().getTime())
.setEndDate(endDate.getTime())
.setKeySize(2048)
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance(RSA, ANDROID_KEY_STORE);
generator.initialize(spec);
generator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
数据加密
try {
Key key = mKeyStore.getKey(alias, null);
if (null != key) {
//取出密钥
PublicKey publicKey = mKeyStore.getCertificate(alias).getPublicKey();
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} else {
Log.e("KeyStoreUtils", "key==null , 没找到私钥");
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
数据解密
try {
PrivateKey privateKey = (PrivateKey) mKeyStore.getKey(alias, null);
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
更多推荐
所有评论(0)