安卓系统提供多种数据存储方式,不同方式的安全性差异较大:
存储方式 | 风险等级 | 主要风险点 |
---|---|---|
内部存储(Internal Storage) | 中高风险 | 设备root后可被任意读取,应用被卸载后数据可能被恢复 |
外部存储(External Storage) | 高风险 | 公共目录可被其他应用/用户直接访问,SD卡可物理拆卸 |
SQLite数据库 | 中高风险 | 未加密的数据库文件可通过Root或ADB工具直接读取 |
SharedPreferences | 中风险 | 配置文件明文存储,设备破解后可直接获取 |
网络存储 | 高风险 | 数据传输过程可能被拦截,服务器存储需额外防护 |
强制数据加密
val key = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) val encryptedData = EncryptedSharedPreferences.create( context, "secret_prefs", key, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM )
权限最小化原则
READ_EXTERNAL_STORAGE
)<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>
密钥安全管理
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); // 生成密钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); keyPairGenerator.initialize(new KeyGenParameterSpec.Builder("myKey", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()); KeyPair keyPair = keyPairGenerator.generateKeyPair();
数据库防护
SQLiteDatabase db = getReadableDatabase(); String selection = "_id=?"; String[] args = {String.valueOf(targetId)}; Cursor cursor = db.query("table_name", null, selection, args, null, null, null);
通信安全
<network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">api.example.com</domain> </domain-config> </network-security-config>
val certificatePinner = "certificatePinningConfig" OkHttpClient.Builder().apply { certificatePinner(certificatePinner) }
场景 | 推荐方案 | 安全增强措施 |
---|---|---|
用户凭证 | EncryptedSharedPreferences | 配合生物识别认证(FingerprintManager) |
本地缓存 | EncryptedFile | 设置文件权限为MODE_PRIVATE ,使用Keystore管理密钥 |
结构化数据 | 加密SQLite数据库 | 启用WAL模式减少数据损坏风险,定期备份加密数据库 |
媒体文件 | EncryptedSharedPreferences | 分块加密存储,元数据与内容分离 |
长期存档 | Cloud HSM服务(如AWS KMS) | 客户端预加密+服务器端密钥管理,启用多区域冗余存储 |
Q1:为什么使用EncryptedSharedPreferences比常规SP安全?
A1:常规SharedPreferences以XML明文存储,设备root后可直接读取,EncryptedSharedPreferences通过Android Keystore生成密钥,采用AES-GCM算法加密数据,即使文件被提取也无法解密。
Q2:如何防止SQLite数据库被逆向分析?
A2:1) 启用数据库加密(如SQLCipher);2) 关键表字段单独加密存储;3) 移除调试符号(ProGuard混淆);4) 添加数据完整性校验(如HMAC签名)。