Android中KeyStore存储类型转换错误及Android KeyStore实现求助
一、修复Java KeyStore的类型转换异常问题
你遇到的ClassCastException是因为错误地将FileOutputStream强制转换为LoadStoreParameter类型——这两个类无继承关系,强制转换必然失败。正确做法是使用KeyStore.store()和load()的带密码参数的重载方法,修正后的代码如下:
KeyStore keyStore; // 替换为实际安全密码,建议避免硬编码,可通过用户输入或安全存储获取 char[] keystorePassword = "your_secure_password".toCharArray(); try { keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); } catch (KeyStoreException e) { e.printStackTrace(); return; } try { // 尝试打开已存在的密钥库 FileInputStream fileInputStream = thisClass_Context.openFileInput("Subs2IPA_Crypto.keystore"); keyStore.load(fileInputStream, keystorePassword); fileInputStream.close(); } catch (FileNotFoundException e) { // 密钥库不存在,创建新的 try { keyStore.load(null, null); // 初始化空密钥库 FileOutputStream fileOutputStream = thisClass_Context.openFileOutput("Subs2IPA_Crypto.keystore", Context.MODE_PRIVATE); keyStore.store(fileOutputStream, keystorePassword); // 使用带密码的重载方法 fileOutputStream.close(); } catch (IOException | NoSuchAlgorithmException | CertificateException ex) { ex.printStackTrace(); } } catch (IOException | NoSuchAlgorithmException | CertificateException e) { e.printStackTrace(); }
二、Android KeyStore 完整实现方案
Android KeyStore是系统级安全存储,密钥不会离开系统硬件(支持TEE的设备),安全性远高于普通Java KeyStore,以下是完整的密钥操作示例:
1. 生成RSA密钥对(自动存储到Android KeyStore)
private void generateAndroidKeyStoreKey(String alias) { try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); // 配置密钥参数,可根据需求调整加密模式、填充方式等 KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder( alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(false) // 按需设置是否需要用户验证(如指纹) .build(); keyPairGenerator.initialize(keyGenParameterSpec); keyPairGenerator.generateKeyPair(); // 密钥已自动存入Android KeyStore,无需手动保存文件 } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) { e.printStackTrace(); } }
2. 从Android KeyStore获取密钥对
private KeyPair getAndroidKeyStoreKey(String alias) { try { KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, null); PublicKey publicKey = keyStore.getCertificate(alias).getPublicKey(); if (privateKey != null && publicKey != null) { return new KeyPair(publicKey, privateKey); } } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | UnrecoverableKeyException e) { e.printStackTrace(); } return null; }
3. 删除Android KeyStore中的密钥
private void deleteAndroidKeyStoreKey(String alias) { try { KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); keyStore.deleteEntry(alias); } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { e.printStackTrace(); } }
4. 使用示例
// 生成密钥,别名需唯一 generateAndroidKeyStoreKey("Subs2IPA_Crypto_Key"); // 获取密钥进行加密/解密操作 KeyPair keyPair = getAndroidKeyStoreKey("Subs2IPA_Crypto_Key"); if (keyPair != null) { // 示例:初始化加密Cipher try { Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] encryptedData = cipher.doFinal("plain_text".getBytes()); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } } // 如需删除密钥 // deleteAndroidKeyStoreKey("Subs2IPA_Crypto_Key");
内容的提问来源于stack exchange,提问作者Carlos Botero
相关产品推荐
相关产品推荐

