# 密钥存储与加密

## 概述

Android系统提供了多种密钥存储和加密机制，用于保护敏感数据和应用密钥。本文档介绍Android密钥存储系统和数据加密方法。

## Android密钥存储系统

### 1. KeyStore系统

#### KeyStore概述
- Android提供的密钥存储系统
- 支持硬件和软件密钥存储
- 保护密钥不被应用直接访问

#### KeyStore类型
- **AndroidKeyStore**: Android密钥存储提供者
- **KeyChain**: 系统级密钥链
- **硬件安全模块**: 硬件支持的密钥存储

### 2. AndroidKeyStore使用

#### 生成密钥
```java
// 生成密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
    KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
    
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
    "my_key_alias",
    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
    .build();
    
keyPairGenerator.initialize(spec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
```

#### 存储密钥
```java
// 密钥自动存储在AndroidKeyStore中
// 不需要手动存储，系统自动管理
```

#### 获取密钥
```java
// 从KeyStore获取密钥
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);

PrivateKey privateKey = (PrivateKey) keyStore.getKey("my_key_alias", null);
PublicKey publicKey = keyStore.getCertificate("my_key_alias").getPublicKey();
```

### 3. 密钥属性

#### 密钥用途
- **PURPOSE_ENCRYPT**: 加密
- **PURPOSE_DECRYPT**: 解密
- **PURPOSE_SIGN**: 签名
- **PURPOSE_VERIFY**: 验证

#### 加密填充
- **ENCRYPTION_PADDING_RSA_PKCS1**: PKCS1填充
- **ENCRYPTION_PADDING_RSA_OAEP**: OAEP填充
- **ENCRYPTION_PADDING_NONE**: 无填充

#### 密钥保护
- **BLOCK_MODE_ECB**: ECB模式
- **BLOCK_MODE_CBC**: CBC模式
- **BLOCK_MODE_GCM**: GCM模式

## 数据加密

### 1. 对称加密

#### AES加密
```java
// 生成AES密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
SecretKey secretKey = keyGenerator.generateKey();

// 加密数据
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());

// 获取IV
byte[] iv = cipher.getIV();
```

#### 解密数据
```java
// 解密数据
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
byte[] decryptedData = cipher.doFinal(encryptedData);
```

### 2. 非对称加密

#### RSA加密
```java
// 使用公钥加密
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());
```

#### RSA解密
```java
// 使用私钥解密
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
```

### 3. 哈希和签名

#### 数据哈希
```java
// SHA-256哈希
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(data.getBytes());
```

#### 数字签名
```java
// 使用私钥签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes());
byte[] signatureBytes = signature.sign();
```

#### 验证签名
```java
// 使用公钥验证
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes());
boolean isValid = signature.verify(signatureBytes);
```

## 密钥管理

### 1. 密钥生成

#### 安全随机数
```java
// 使用SecureRandom生成随机数
SecureRandom random = new SecureRandom();
byte[] randomBytes = new byte[32];
random.nextBytes(randomBytes);
```

#### 密钥派生
```java
// 使用PBKDF2派生密钥
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
SecretKey key = factory.generateSecret(spec);
```

### 2. 密钥存储

#### SharedPreferences加密存储
```java
// 使用EncryptedSharedPreferences
String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    "prefs",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
```

#### 文件加密存储
```java
// 加密文件
File encryptedFile = new File(context.getFilesDir(), "encrypted_data");
FileOutputStream fos = new FileOutputStream(encryptedFile);

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);

cos.write(data.getBytes());
cos.close();
```

### 3. 密钥轮换

#### 密钥版本管理
```java
// 密钥版本管理
public class KeyManager {
    private static final String KEY_ALIAS_PREFIX = "key_v";
    private static final int CURRENT_KEY_VERSION = 2;
    
    public String getCurrentKeyAlias() {
        return KEY_ALIAS_PREFIX + CURRENT_KEY_VERSION;
    }
    
    public void rotateKey() {
        // 生成新密钥
        generateKey(CURRENT_KEY_VERSION + 1);
        // 迁移数据
        migrateData(CURRENT_KEY_VERSION, CURRENT_KEY_VERSION + 1);
    }
}
```

## 硬件安全模块

### 1. 硬件支持的密钥存储

#### 检查硬件支持
```java
// 检查硬件支持的密钥算法
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);

Set<String> supportedAlgorithms = keyStore.getProvider()
    .getServices().stream()
    .filter(service -> service.getType().equals("Cipher"))
    .map(Provider.Service::getAlgorithm)
    .collect(Collectors.toSet());
```

#### 使用硬件密钥
```java
// 生成硬件支持的密钥
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
    "hardware_key",
    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
    .setIsStrongBoxBacked(true)  // 使用StrongBox
    .build();
```

### 2. StrongBox

#### StrongBox概述
- 硬件安全模块
- 提供更强的安全保护
- 支持密钥存储和加密操作

#### StrongBox使用
```java
// 检查StrongBox支持
KeyInfo keyInfo = (KeyInfo) keyFactory.getKeySpec(key, KeyInfo.class);
boolean isStrongBoxBacked = keyInfo.isInsideSecureHardware();
```

## 加密算法选择

### 1. 对称加密算法

#### AES
- **推荐**: AES-256-GCM
- **用途**: 数据加密
- **优势**: 性能好，安全性高

#### ChaCha20
- **推荐**: ChaCha20-Poly1305
- **用途**: 数据加密
- **优势**: 性能好，适合移动设备

### 2. 非对称加密算法

#### RSA
- **推荐**: RSA-2048或RSA-4096
- **用途**: 密钥交换、数字签名
- **优势**: 广泛支持

#### ECC
- **推荐**: ECDSA-P256
- **用途**: 数字签名
- **优势**: 密钥短，性能好

### 3. 哈希算法

#### SHA-256
- **推荐**: SHA-256
- **用途**: 数据完整性验证
- **优势**: 安全性高，性能好

## 安全最佳实践

### 1. 密钥管理
- 使用AndroidKeyStore存储密钥
- 定期轮换密钥
- 使用硬件安全模块（如果可用）
- 避免硬编码密钥

### 2. 数据加密
- 敏感数据必须加密
- 使用强加密算法
- 安全存储加密密钥
- 传输时使用HTTPS

### 3. 密钥保护
- 不在日志中输出密钥
- 不在代码中硬编码密钥
- 使用安全的密钥派生方法
- 及时清除内存中的密钥

## 常见问题

### 1. 密钥丢失

#### 问题
- 密钥无法恢复
- 数据无法解密

#### 解决
- 备份密钥（安全方式）
- 使用密钥恢复机制
- 避免密钥丢失

### 2. 性能问题

#### 问题
- 加密解密性能影响

#### 解决
- 选择合适的算法
- 使用硬件加速
- 优化加密操作

### 3. 兼容性问题

#### 问题
- 不同设备支持不同

#### 解决
- 检查设备支持
- 提供降级方案
- 充分测试

## 相关链接

- [[README]]
- [[权限管理框架]]
- [[漏洞案例库]]
