- KeyStore简介
- KeyStore使用
#1. KeyStore简介
基于安全考虑,一般一些敏感的本地化的数据会进行加密处理。一般的手段就是使用对称加密(AES)或者非对称加密(RSA)或者其他的密码算法对数据进行加密处理,基于保护秘钥不保护加密算法的原则。所以核心的问题是怎么安全的保存加密数据的秘钥来构建尽可能安全的防护体系。
基于android系统,我们可以尝试使用系统提供的Android KeyStore系统来存储并管理加密密钥。秘钥进入KeyStore后,可以将它们用于加密操作,而秘钥材料仍不可到出。此外,它提供了秘钥使用时间和方式限制措施,例如要求进行用户身份验证才能使用秘钥,或者限制只能在某些加密模式中使用。
#2. KeyStore使用
关于下面的code的几点说明:
- 秘钥存储在KeyStore中,通过alias创建并获取秘钥。
- 加密的测试代码是基于AES256 CBC模式,初始化向量部分是系统随机生成并且在加密成功后返回的。
public class EncryptionUtils {
private static final String ALGORITHM = "AES/CBC/PKCS7Padding";
private Pair<byte[], byte[]> encryptionPair;
@RequiresApi(api = Build.VERSION_CODES.M)
private void encryptText(String plainText) {
encryptionPair = encrypt(ALGORITHM, getEncryptKeyFromStore(ALIAS), plainText.getBytes());
if (encryptionPair == null) {
return;
}
tvText.setText(byteArrayToHexStr(encryptionPair.first));
}
@RequiresApi(api = Build.VERSION_CODES.M)
private byte[] decryptText() {
IvParameterSpec iv = new IvParameterSpec(encryptionPair.second);
return decrypt(ALGORITHM, getEncryptKeyFromStore(ALIAS), iv, encryptionPair.first);
}
private Pair<byte[], byte[]> encrypt(String algorithm, Key key, byte[] plainText) {
try {
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, key);
return new Pair<>(cipher.doFinal(plainText), cipher.getIV());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
private byte[] decrypt(String algorithm, Key key, IvParameterSpec iv, byte[] cipherText) {
try {
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
@RequiresApi(api = Build.VERSION_CODES.M)
private Key getEncryptKeyFromStore(String alias) {
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
if (ks.containsAlias(alias)) {
return ks.getKey(alias, null);
}
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore");
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setKeySize(256)
.build();
keyGenerator.init(spec);
return keyGenerator.generateKey();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
private String byteArrayToHexStr(byte[] byteArray) {
if (byteArray == null) {
return null;
}
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[byteArray.length * 2];
for (int j = 0; j < byteArray.length; j++) {
int v = byteArray[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
![](https://img.haomeiwen.com/i9426186/1b83dd1170a03dd5.jpg)
![](https://img.haomeiwen.com/i9426186/cc0725d7df9c0b84.png)
网友评论