我们的产品经理希望在我们的应用程序中使用4位密码登录,这显然是出于用户体验的原因,因此用户每次登录时不必记住密码。
刷新令牌可以从后端检索以获得会话令牌,会话令牌可以访问API。在我们的应用程序上,我们使用AES和PBKDF2加密刷新令牌。生成一个随机salt和IV,再加上用作PBKDF2密码的4位数字。
加密后,我存储salt、IV和以私有共享偏好编码的密码文本base64。
加密代码如下:
const val CPR_TRANSFORMATION = "AES/CBC/PKCS7Padding"
const val ALGORITHM_TYPE = "PBKDF2WithHmacSHA1"
const val ITERATION_AMOUNT = 12000
const val KEY_SIZE = 256
private fun encrypt(passCode: String, data: ByteArray): Encrypted { //e.g.: passCode = "0000"
val salt = ByteArray(256)
SecureRandom().nextBytes(salt)
val iv = ByteArray(16)
SecureRandom().nextBytes(iv)
val cipher = Cipher.getInstance(CPR_TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(passCode, salt), IvParameterSpec(iv))
val raw = cipher.doFinal(data)
return Encrypted(salt.encodeBase64(), iv.encodeBase64(), raw.encodeBase64())
}
private fun getSecretKey(passCode: String, salt: ByteArray): Key {
val pbKeySpec = PBEKeySpec(passCode.toCharArray(), salt, ITERATION_AMOUNT, KEY_SIZE)
val keyBytes = SecretKeyFactory.getInstance(ALGORITHM_TYPE).generateSecret(pbKeySpec).encoded
return SecretKeySpec(keyBytes, KeyProperties.KEY_ALGORITHM_AES)
}
现在我的问题是:这个实现有多安全
- 攻击者如何从共享中检索刷新令牌偏好并解密
- 对称密钥在安全元件内吗
- 此实现对恶意软件或root的安全性如何
- 这把钥匙有多容易?(用户尝试10k除外手动插入正确销的次数(
攻击者如何从共享首选项中检索刷新令牌并对其进行解密?
我不清楚如何检索,我不确定如何在Android中从共享偏好中检索值。解密很简单,攻击者强行使用4位PIN。再多的拖延也无济于事。
对称密钥在安全元素内吗?
不,它在PBKDF2操作之后在内存中。
此实现对恶意软件或root的安全性如何?
不是那么安全,基本上你希望他们不会对破解PIN感兴趣。
暴力强制密钥有多容易?(除了用户手动尝试10k次插入正确的引脚(
除了之外,是什么意思?检索密钥的唯一方法是:
- 来破解PBKDF2并尝试解密(这是迄今为止最明显的(
- 以某种方式读出CCD_ 1的存储器(更难(
- 对AES实现执行可能泄露密钥的侧通道攻击(如果你现在使用一个好的Android实现,那就相当棘手了(
基本上,只有在可以限制猜测操作数量的情况下,才能使用PIN。加密值似乎并非如此。
顺便说一句,大于16到32字节的salt是没有意义的。在base64编码之前,连接salt、IV和密文更有意义(并且返回具有这些已经编码的值的对象根本没有意义(。12K操作似乎很多,但现在计算机很快,你可能想让这个值可配置&更高。
此实现的安全性如何?
我决不是密码专家,但我可以提供一些上下文,因为我目前正在重构类似的实现。使用PBKDF2加密您的代币将被渗透测试机构标记为中等严重性,我们的实现使用6位密码。