?
在 Android 中,AndroidKeyStore 是一個安全的存儲系統,用于存儲加密密鑰。它提供了一種安全的方式來生成、存儲和管理密鑰,而無需將密鑰暴露給應用程序本身。以下是如何使用 AndroidKeyStore 的基本步驟和示例代碼。
檢查 AndroidKeyStore 是否可用
AndroidKeyStore 在 Android API 18(Android 4.3)及以上版本中可用。確保你的應用支持這些版本。if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {// AndroidKeyStore 不可用return;
}
完整 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); // 加載 AndroidKeyStorereturn keyStore.getCertificate(alias).getPublicKey();}/*** 獲取私鑰*/public static PrivateKey getPrivateKey(String alias) throws Exception {KeyStore keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE);keyStore.load(null); // 加載 AndroidKeyStorereturn (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
來安全地生成密鑰、加密和解密數據。如果有進一步的問題,請隨時提問!