官方文档:https://developer.android.com/training/articles/keystore.html#UsingAndroidKeyStore
一、Android KeyStore的应用
1、存储密匙:Android提供的这个KeyStore最大的作用就是不需要开发者去维护这个密匙的存储问题,相比起存储在用户的数据空间或者是外部存储器都更加安全。注意的是这个密匙随着用户清除数据或者卸载应用都会被清除掉。
3、对称加密算法生成密匙与获取,注意这个alias是keystore存储该密匙的别名,通过这个别名可以获取这个密匙的相关数据。相关代码如下:
一、Android KeyStore的应用
1、存储密匙:Android提供的这个KeyStore最大的作用就是不需要开发者去维护这个密匙的存储问题,相比起存储在用户的数据空间或者是外部存储器都更加安全。注意的是这个密匙随着用户清除数据或者卸载应用都会被清除掉。
2、得益于Android独立的一套密匙库系统,可以提高安全性
二、实例:
1、前提:Android安全相关特性是从Android6.0开始有较大的改动,而KeyStore就是一个很好的体现,很多新特性(如KeyGenParameterSpec)都是从6.0才开始加入的,因此对于低版本应用需要做另外的兼容。
2、初始化KeyStore,代码如下
public void initKeyStore() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3、对称加密算法生成密匙与获取,注意这个alias是keystore存储该密匙的别名,通过这个别名可以获取这个密匙的相关数据。相关代码如下:
public void createSecretKey(String alias) {
if (hasAlias(alias)) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore");
try {
//AES算法用于加密与解密,具体参考KeyGenParameterSpec类注释
keyGenerator.init(new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE).build());
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
SecretKey key = keyGenerator.generateKey();
Log.d(TAG, "SecretKey:" + key);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
}
}
public SecretKey getSecretKey(String alias) {
try {
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
Log.d(TAG, "SecretKey:" + secretKey);
return secretKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return null;
}
private boolean hasAlias(String alias) {
try {
return keyStore != null && keyStore.containsAlias(alias);
} catch (KeyStoreException e) {
e.printStackTrace();
}
return false;
}
4、非对称加密算法密匙对的生成与获取,代码如下:
public void createKeyPair(String alias) {
if (hasAlias(alias)) {
return;
}
KeyPairGenerator keyPairGenerator;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
//RSA算法用于签名与校验,具体参考KeyGenParameterSpec类注释
keyPairGenerator.initialize(new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_SIGN |
KeyProperties.PURPOSE_VERIFY).setDigests(KeyProperties.DIGEST_SHA256, KeyProperties
.DIGEST_SHA512).build());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Log.d(TAG, "createKeyPair>>PrivateKey:" + keyPair.getPrivate() + ",PublicKey:" + keyPair.getPublic());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
}
}
public KeyPair getTargetKeyPair(String alias) {
try {
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null);
PublicKey publicKey = entry.getCertificate().getPublicKey();
PrivateKey privateKey = entry.getPrivateKey();
Log.d(TAG, "getTargetKeyPair>>privateKey:" + privateKey + ",publicKey:" + publicKey);
return new KeyPair(publicKey, privateKey);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
}
return null;
}
5、测试实例,代码如下
public void printAliases() {
try {
Enumeration<String> aliases = keyStore.aliases();
while (aliases != null && aliases.hasMoreElements()) {
String alias = aliases.nextElement();
Log.d(TAG, "aliases:" + alias);
}
} catch (KeyStoreException e) {
e.printStackTrace();
}
}
public static void test() {
KeyStoreHelper helper = new KeyStoreHelper();
helper.initKeyStore();
helper.printAliases();
String aesAlias = "hello aes key";
helper.createSecretKey(aesAlias);
helper.getSecretKey(aesAlias);
helper.printAliases();
String rsaAlias = "hello rsa key";
helper.createKeyPair(rsaAlias);
helper.getTargetKeyPair(rsaAlias);
helper.printAliases();
}