如何为登录应用的数据库应用SQLCipher及KeyStore加密方案?
Android 可复用登录应用加密实现指南
一、基于KeyStore的安全加密方案(推荐)
既然你已经生成了密钥,接下来分两步完成加密存储和验证:
1. 加密用户密码并存储
- 拿到生成的KeyStore密钥后,使用AES/GCM模式加密用户输入的密码(GCM自带完整性校验,比ECB/CBC更安全)
- 代码示例:
// 假设你已从KeyStore获取到SecretKey对象 fun encryptPassword(password: String, secretKey: SecretKey): Pair<ByteArray, ByteArray> { val cipher = Cipher.getInstance("AES/GCM/NoPadding") cipher.init(Cipher.ENCRYPT_MODE, secretKey) val iv = cipher.iv // 保存这个IV,解密时需要用 val encryptedPassword = cipher.doFinal(password.toByteArray(Charsets.UTF_8)) return Pair(encryptedPassword, iv) }
- 把加密后的密码、IV和用户名一起存入本地数据库(比如Room),注意IV要和对应密码绑定存储
2. 登录时解密验证
- 从数据库取出用户名对应的加密密码和IV
- 用相同的KeyStore密钥和IV解密,再和用户输入的密码比对
- 代码示例:
fun decryptPassword(encryptedPassword: ByteArray, iv: ByteArray, secretKey: SecretKey): String { val cipher = Cipher.getInstance("AES/GCM/NoPadding") val spec = GCMParameterSpec(128, iv) // 128是GCM的标签长度 cipher.init(Cipher.DECRYPT_MODE, secretKey, spec) val decryptedBytes = cipher.doFinal(encryptedPassword) return String(decryptedBytes, Charsets.UTF_8) }
- 比对解密后的字符串和用户输入的密码,一致则验证通过
二、简便替代方案(快速实现)
如果暂时不想深入KeyStore,可使用哈希加盐的方式:
- 给每个用户生成唯一的随机盐值
- 用SHA-256或SHA-512将密码和盐值拼接后哈希
- 存储用户名、盐值和哈希结果
- 登录时用同样的盐值哈希用户输入的密码,再和存储的哈希值比对
- 代码示例:
fun hashPassword(password: String, salt: ByteArray): ByteArray { val spec = PBEKeySpec(password.toCharArray(), salt, 10000, 256) val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") return factory.generateSecret(spec).encoded }
- 注意:哈希是单向的,无法还原密码,适合只需要验证的场景
三、可复用登录应用的优化点
- 把加密/解密、哈希逻辑封装成单独的工具类,方便其他应用直接调用
- UI层和加密逻辑解耦,通过接口传递数据,适配不同UI时只需替换视图层
- 数据库操作也封装成通用的DAO,支持快速切换不同存储方案
内容的提问来源于stack exchange,提问作者trevor-leon
相关产品推荐
相关产品推荐

