在线网站设计工具,商城建站报价方案,紧急通知页面升级,大连网站设计案例Android 密钥库系统https://developer.android.google.cn/privacy-and-security/keystore?hlzh-cnAndroid Keystore 系统的核心设计目标之一#xff0c;就是确保密钥材料#xff08;Key Material#xff09;难以从设备中提取#xff0c;并且通常无法在其他设备中使用。它…Android 密钥库系统https://developer.android.google.cn/privacy-and-security/keystore?hlzh-cnAndroid Keystore 系统的核心设计目标之一就是确保密钥材料Key Material难以从设备中提取并且通常无法在其他设备中使用。它在内部生成一个密钥我们可以用它来加解密数据并不能把我们自己生成的密钥送进去。Android Keystore 是一个系统服务它提供了一个安全的容器来生成、存储和管理加密密钥并确保密钥材料本身难以从设备中提取。Android Keystore 是一个安全的密钥管理系统而不仅仅是一个简单的密钥存储库。它负责密钥的全生命周期管理生成、存储、使用并确保密钥材料的安全。Android Keystore 系统提供了一种安全的方式来生成、存储和使用加密密钥确保密钥材料难以从设备中提取以下示例展示如何使用 Java 代码生成密钥、检查其是否受硬件支持、进行数据加密和解密以及验证签名。
1. 生成密钥 
首先使用 KeyPairGenerator 生成一个 RSA 密钥对并将其存储在 Android Keystore 中。密钥生成时会指定用途如加密、解密、签名、验证、摘要算法、是否需要用户认证等参数。
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;// 生成非对称密钥对例如 RSA 或 EC
public KeyPair generateKeyPair(String alias, boolean requireAuth) throws Exception {KeyPairGenerator keyPairGenerator  KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);KeyGenParameterSpec.Builder builder  new KeyGenParameterSpec.Builder(alias,KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY).setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1).setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1).setKeySize(2048);if (requireAuth) {builder.setUserAuthenticationRequired(true);// 设置认证有效期秒或每次操作都需要认证// builder.setUserAuthenticationValidityDurationSeconds(300);}keyPairGenerator.initialize(builder.build());return keyPairGenerator.generateKeyPair();
}// 生成对称密钥例如 AES
public SecretKey generateSymmetricKey(String alias) throws Exception {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_GCM).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE).setKeySize(256).build();keyGenerator.init(spec);return keyGenerator.generateKey();
}2. 检查密钥的硬件支持 
生成密钥后可以检查密钥是否存储在硬件安全模块如 TEE 或 StrongBox中。
import android.security.keystore.KeyInfo;
import java.security.KeyFactory;public void checkKeySecurityLevel(String alias) throws Exception {KeyStore keyStore  KeyStore.getInstance(AndroidKeyStore);keyStore.load(null);KeyStore.Entry entry  keyStore.getEntry(alias, null);if (entry instanceof KeyStore.PrivateKeyEntry) {PrivateKey privateKey  ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();KeyFactory factory  KeyFactory.getInstance(privateKey.getAlgorithm(), AndroidKeyStore);KeyInfo keyInfo  factory.getKeySpec(privateKey, KeyInfo.class);boolean isInsideSecureHardware  keyInfo.isInsideSecureHardware();int securityLevel  KeyProperties.SECURITY_LEVEL_SOFTWARE;if (Build.VERSION.SDK_INT  Build.VERSION_CODES.S) {securityLevel  keyInfo.getSecurityLevel();if (securityLevel  KeyProperties.SECURITY_LEVEL_TRUSTED_ENVIRONMENT) {System.out.println(Key is in Trusted Execution Environment (TEE));} else if (securityLevel  KeyProperties.SECURITY_LEVEL_STRONGBOX) {System.out.println(Key is in StrongBox);} else {System.out.println(Key is in software);}} else {System.out.println(isInsideSecureHardware:   isInsideSecureHardware);}}
}3. 使用密钥进行加密和解密 
使用生成的密钥进行加密和解密操作。以下示例使用 RSA 非对称加密。
import javax.crypto.Cipher;public byte[] encryptData(String alias, byte[] data) throws Exception {KeyStore keyStore  KeyStore.getInstance(AndroidKeyStore);keyStore.load(null);KeyStore.Entry entry  keyStore.getEntry(alias, null);if (entry instanceof KeyStore.PrivateKeyEntry) {PublicKey publicKey  ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey();Cipher cipher  Cipher.getInstance(RSA/ECB/PKCS1Padding);cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}throw new Exception(No such key or not a private key entry);
}public byte[] decryptData(String alias, byte[] encryptedData) throws Exception {KeyStore keyStore  KeyStore.getInstance(AndroidKeyStore);keyStore.load(null);KeyStore.Entry entry  keyStore.getEntry(alias, null);if (entry instanceof KeyStore.PrivateKeyEntry) {PrivateKey privateKey  ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();Cipher cipher  Cipher.getInstance(RSA/ECB/PKCS1Padding);cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(encryptedData);}throw new Exception(No such key or not a private key entry);
}4. 使用密钥进行签名和验证 ✍️
使用密钥对数据进行签名和验证确保数据完整性和来源可信。
import java.security.Signature;public byte[] signData(String alias, byte[] data) throws Exception {KeyStore keyStore  KeyStore.getInstance(AndroidKeyStore);keyStore.load(null);KeyStore.Entry entry  keyStore.getEntry(alias, null);if (entry instanceof KeyStore.PrivateKeyEntry) {PrivateKey privateKey  ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();Signature signature  Signature.getInstance(SHA256withRSA);signature.initSign(privateKey);signature.update(data);return signature.sign();}throw new Exception(No such key or not a private key entry);
}public boolean verifyData(String alias, byte[] data, byte[] signatureBytes) throws Exception {KeyStore keyStore  KeyStore.getInstance(AndroidKeyStore);keyStore.load(null);KeyStore.Entry entry  keyStore.getEntry(alias, null);if (entry instanceof KeyStore.PrivateKeyEntry) {PublicKey publicKey  ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey();Signature signature  Signature.getInstance(SHA256withRSA);signature.initVerify(publicKey);signature.update(data);return signature.verify(signatureBytes);}throw new Exception(No such key or not a private key entry);
}5. 注意事项 ⚠️
密钥别名: 每个密钥需要一个唯一的别名用于在 Keystore 中标识和检索。用户认证: 如果设置了 setUserAuthenticationRequired(true)使用密钥时需要用户认证如指纹、PIN、图案等。如果认证方式被移除密钥将永久失效。算法和模式支持: 不同设备和 Android 版本支持的算法和模式可能不同建议检查设备支持情况。错误处理: 所有操作都应妥善处理异常如 KeyStoreException、NoSuchAlgorithmException、InvalidKeyException 等。
6. 完整流程示例 
以下是一个完整的示例从生成密钥到使用它进行加密和解密
public void fullKeyUsageExample() {String alias  my_key_alias;try {// 1. 生成密钥KeyPair keyPair  generateKeyPair(alias, false);// 2. 检查硬件支持checkKeySecurityLevel(alias);// 3. 加密数据String originalData  Sensitive data;byte[] encryptedData  encryptData(alias, originalData.getBytes(StandardCharsets.UTF_8));// 4. 解密数据byte[] decryptedData  decryptData(alias, encryptedData);String decryptedString  new String(decryptedData, StandardCharsets.UTF_8);// 5. 签名数据byte[] signature  signData(alias, originalData.getBytes(StandardCharsets.UTF_8));// 6. 验证签名boolean isValid  verifyData(alias, originalData.getBytes(StandardCharsets.UTF_8), signature);} catch (Exception e) {e.printStackTrace();}
}