在 Android 中,AndroidKeyStore 是一个安全的存储系统,用于存储加密密钥。它提供了一种安全的方式来生成、存储和管理密钥,而无需将密钥暴露给应用程序本身。以下是如何使用 AndroidKeyStore 的基本步骤和示例代码。
检查 AndroidKeyStore 是否可用
cpp
AndroidKeyStore 在 Android API 18(Android 4.3)及以上版本中可用。确保你的应用支持这些版本。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
// AndroidKeyStore 不可用
return;
}
完整 Java 示例
java
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
public class AndroidKeyStoreExample {
// 密钥库类型
private static final String PP_KEYSTORE_TYPE = "AndroidKeyStore";
// 密钥库别名
private static final String PP_KEYSTORE_ALIAS = "pp_keystore_alias";
// 加密算法标准名称
private static final String PP_TRANSFORMATION = "RSA/ECB/PKCS1Padding";
public static void main(String[] args) {
try {
// 创建 RSA 密钥对
createRsaKeyPair(PP_KEYSTORE_ALIAS);
// 获取公钥和私钥
PublicKey publicKey = getPublicKey(PP_KEYSTORE_ALIAS);
PrivateKey privateKey = getPrivateKey(PP_KEYSTORE_ALIAS);
// 原始数据
String originalText = "Hello, AndroidKeyStore!";
System.out.println("Original Text: " + originalText);
// 使用公钥加密数据
byte[] encryptedData = encryptData(publicKey, originalText.getBytes(StandardCharsets.UTF_8));
System.out.println("Encrypted Data: " + new String(encryptedData, StandardCharsets.UTF_8));
// 使用私钥解密数据
byte[] decryptedData = decryptData(privateKey, encryptedData);
System.out.println("Decrypted Data: " + new String(decryptedData, StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建 RSA 密钥对
*/
public static void createRsaKeyPair(String alias) throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA, PP_KEYSTORE_TYPE
);
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build();
keyPairGenerator.initialize(spec);
keyPairGenerator.generateKeyPair();
}
/**
* 获取公钥
*/
public static PublicKey getPublicKey(String alias) throws Exception {
KeyStore keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE);
keyStore.load(null); // 加载 AndroidKeyStore
return keyStore.getCertificate(alias).getPublicKey();
}
/**
* 获取私钥
*/
public static PrivateKey getPrivateKey(String alias) throws Exception {
KeyStore keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE);
keyStore.load(null); // 加载 AndroidKeyStore
return (PrivateKey) keyStore.getKey(alias, null);
}
/**
* 使用公钥加密数据
*/
public static byte[] encryptData(PublicKey publicKey, byte[] data) throws Exception {
Cipher cipher = Cipher.getInstance(PP_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 使用私钥解密数据
*/
public static byte[] decryptData(PrivateKey privateKey, byte[] encryptedData) throws Exception {
Cipher cipher = Cipher.getInstance(PP_TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
}
}
代码说明
1. 创建 RSA 密钥对
- 使用
KeyPairGenerator
和KeyGenParameterSpec
创建一个 RSA 密钥对。 KeyGenParameterSpec.Builder
用于指定密钥的用途(加密和解密)、填充方式等配置。
2. 获取公钥和私钥
- 公钥通过
KeyStore.getCertificate(alias).getPublicKey()
获取。 - 私钥通过
KeyStore.getKey(alias, null)
获取。
3. 加密数据
- 使用公钥和指定的加密算法(
RSA/ECB/PKCS1Padding
)对数据进行加密。
4. 解密数据
- 使用私钥和相同的加密算法对加密后的数据进行解密。
运行结果
假设原始数据是 "Hello, AndroidKeyStore!"
,运行程序后会输出:
Original Text: Hello, AndroidKeyStore!
Encrypted Data: [加密后的二进制数据]
Decrypted Data: Hello, AndroidKeyStore!
注意事项
-
API 版本要求:
AndroidKeyStore
支持 API 18 及以上版本。- 如果需要在更低版本中实现类似功能,可以考虑使用其他加密库(如 Bouncy Castle)。
-
异常处理:
- 在实际开发中,务必捕获并处理可能抛出的异常,例如:
KeyStoreException
NoSuchAlgorithmException
InvalidKeyException
IllegalBlockSizeException
BadPaddingException
- 在实际开发中,务必捕获并处理可能抛出的异常,例如:
-
安全性:
- 使用
setUserAuthenticationRequired(true)
可以要求用户认证(如指纹或 PIN 码)才能访问密钥。 - 避免将敏感数据存储在内存中太久,减少泄露风险。
- 使用
-
填充方式:
PKCS1Padding
是常用的填充方式,但如果你需要更高的安全性,可以考虑更现代的填充方式(如 OAEP)。
通过以上代码和解释,你应该能够理解如何在 Android 应用中使用 AndroidKeyStore
来安全地生成密钥、加密和解密数据。如果有进一步的问题,请随时提问!