当前位置:首页 > 行业动态 > 正文

安卓安全的操作数据库

安卓数据库操作安全基础

安卓应用主要使用SQLite数据库存储数据,需注意以下安全风险:

安卓安全的操作数据库  第1张

  1. 明文存储风险:未加密的数据库文件可被root设备直接读取
  2. SQL注入破绽:动态拼接SQL语句可能导致反面代码执行
  3. 权限泄露风险:ContentProvider配置不当可能导致数据越权访问
  4. 备份破绽:未加密的数据库可能通过adb备份泄露

安全操作实践对照表

风险类型 不安全做法 安全做法
SQL注入 SQLiteDatabase.execSQL("SELECT FROM users WHERE name='"+inputName+"'") 使用占位符和SQLiteStatement参数绑定
数据加密 明文存储用户密码、token等敏感信息 使用AES加密敏感字段,密钥存储在Keystore
权限控制 暴露ContentProvider且未设置权限 配置android:exported="false",使用自定义权限
文件存储 数据库文件存储在常规目录 使用getDatabasePath().getAbsolutePath()获取路径,设置文件权限为600

关键防护措施

  1. 参数化查询
    // 不安全示例
    String sql = "SELECT  FROM users WHERE id=" + userId;
    Cursor cursor = db.rawQuery(sql, null);

// 安全示例
String sql = “SELECT FROM users WHERE id=?”;
Cursor cursor = db.rawQuery(sql, new String[]{String.valueOf(userId)});


2. 数据加密方案:
```java
// 使用SQLCipher加密数据库
NetSqlAdapter adapter = new NetSqlAdapter(context, "encrypted.db");
SQLiteDatabase db = adapter.openDatabase();
// 字段级加密示例(AES)
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(plaintext.getBytes());
  1. 权限最小化配置
    <provider
     android:name=".MyContentProvider"
     android:exported="false"
     android:permission="com.example.MY_READ_PERMISSION"/>

敏感数据保护清单

数据类型 保护措施
用户密码 哈希存储(BCrypt/PBKDF2)+ 盐值
支付Token AES-256加密存储,独立密钥管理
身份认证 结合设备指纹/生物识别特征
密钥存储 使用Android Keystore系统

常见破绽防御对照

  1. SQL注入防御
  • 禁用Dynamic SQL
  • 使用ORM框架(如Room)的参数绑定功能
  • 特殊字符转义处理
  1. 数据库文件防护
  • 启用SQLite数据库的WAL模式时限制文件权限
  • 使用File-based encryption(FBE)特性
  • 数据库文件存储路径随机化处理

相关问题与解答

Q1:如何检测应用是否存在SQL注入破绽?
A1:可通过以下方式检测:

  1. 使用Burp Suite拦截SQL查询,尝试注入' OR 1=1 --等payload
  2. 审查所有数据库操作代码,查找字符串拼接场景
  3. 使用SQLMap等自动化工具扫描(需配置代理)
  4. 开启StrictMode检测未处理的异常查询

Q2:Android Keystore系统如何生成数据库加密密钥?
A2:实现步骤:

  1. 调用KeyGenParameterSpec.Builder设置密钥属性:
    KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder("db_key",
     KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
     .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .build();
  2. 通过KeyGenerator创建密钥:
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);
    KeyGenerator generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    generator.init(spec);
    SecretKey key = generator.generateKey();
  3. 使用生成的密钥进行数据库加密
0