12、Android 11 (API 30) 适配:一次性认证、认证白名单、隐私保护增强
Android 11 这次更新,说实话,对生物识别 API 的改动挺大的。我当年从 Android 10 迁移到 11 的时候,踩了不少坑。今天咱们就聊聊这三个核心点:一次性认证、认证白名单、还有隐私保护增强。
说白了,Google 在 Android 11 里把生物识别的安全模型重新梳理了一遍。以前有些模糊的地方,现在都明确了。你想想看,如果你的 App 还在用旧的方式,在 Android 11 设备上可能直接就崩了。
12.1 一次性认证(One-time Authentication)
什么叫一次性认证?就是用户验证一次指纹或虹膜,拿到一个短期有效的密钥,然后这个密钥只能用一次。用完就废了。
我有个项目是做移动支付的,用户每次付款都要重新刷脸。以前的做法是每次调用 authenticate(),但 Android 11 给了我们更优雅的方案。
核心变化: Android 11 引入了 BiometricPrompt.AuthenticationCallback 的新回调方法,明确区分了「一次性」和「持续性」认证。
来看代码:
// Android 11 推荐的一次性认证方式
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("验证身份")
.setSubtitle("请扫描虹膜或指纹")
.setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
.setConfirmationRequired(true) // 关键:要求用户确认
.build();
BiometricPrompt biometricPrompt = new BiometricPrompt(
activity,
executor,
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(
@NonNull BiometricPrompt.AuthenticationResult result) {
// 一次性认证成功
// 注意:这个结果只能用一次
CryptoObject cryptoObject = result.getCryptoObject();
// 用 cryptoObject 做签名或加密
}
}
);
biometricPrompt.authenticate(promptInfo);
我的经验: 如果你设置了 setConfirmationRequired(true),用户必须主动确认(比如按一下按钮)才算认证成功。这在支付场景里特别重要,防止误触。
为什么会这样设计?因为有些场景下,你只想让用户验证一次,比如解锁一个加密文件。验证通过后,文件解密,密钥就失效了。下次再访问,还得重新验证。
12.2 认证白名单(Authentication Whitelist)
这个功能我特别喜欢。Android 11 允许你指定哪些生物识别方式可以用于认证。说白了,就是白名单机制。
以前你只能笼统地说「我要用生物识别」,但到底是虹膜、指纹还是人脸?你控制不了。现在你可以精确指定。
| 认证方式 | 常量值 | 说明 |
|---|---|---|
| 强生物识别 | BIOMETRIC_STRONG |
虹膜、指纹、人脸(Class 3) |
| 弱生物识别 | BIOMETRIC_WEAK |
人脸(Class 2) |
| 设备凭据 | DEVICE_CREDENTIAL |
PIN、图案、密码 |
我建议你这样组合使用:
// 只允许虹膜或指纹(强生物识别),不允许人脸
int authenticators = BIOMETRIC_STRONG;
// 或者:强生物识别 + 设备密码作为备用
int authenticators = BIOMETRIC_STRONG | DEVICE_CREDENTIAL;
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("验证身份")
.setAllowedAuthenticators(authenticators)
.build();
注意: 如果你只设置了 BIOMETRIC_STRONG,但设备上没有虹膜或指纹传感器,那认证会直接失败。所以最好加上 DEVICE_CREDENTIAL 作为 fallback。
我曾经在一个项目里只用了 BIOMETRIC_STRONG,结果测试机是台只有人脸识别的平板,直接报错。嗯,从那以后我再也不敢不加 fallback 了。
12.3 隐私保护增强
Android 11 在隐私方面做了不少改进。对于生物识别来说,最明显的变化是:你无法再获取生物识别数据的 hash 或特征值了。
以前有些开发者会偷偷拿指纹特征做设备指纹,现在这条路被堵死了。Google 明确说了:BiometricPrompt 只告诉你「认证成功」或「认证失败」,不给你任何生物特征数据。
来看一个典型的隐私保护场景:
// Android 11 之前(不推荐)
FingerprintManager fingerprintManager =
(FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
// 这里可以获取到一些底层信息,但 Android 11 已经废弃了
// Android 11 推荐方式
BiometricPrompt biometricPrompt = new BiometricPrompt(
activity,
executor,
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(
@NonNull BiometricPrompt.AuthenticationResult result) {
// 你只能知道认证成功了
// 无法获取任何生物特征数据
// 这才是正确的隐私保护做法
}
}
);
隐私保护要点:
- 认证结果不包含生物特征数据
- 认证失败时不提供具体原因(是手指没放好还是虹膜没对准?不告诉你)
- App 无法区分不同的生物特征(比如区分左眼和右眼)
你想想看,这样设计的好处是什么?就算你的 App 被逆向工程了,攻击者也拿不到用户的生物特征。因为你的 App 压根就没接触过这些数据。
12.4 知识体系总览
下面这张图是我整理的 Android 11 生物识别适配的核心逻辑,你看一眼就明白了:
你看,这三个模块其实是环环相扣的。一次性认证解决了「用一次还是用多次」的问题,白名单解决了「用什么方式认证」的问题,隐私保护解决了「数据安不安全」的问题。
我的建议: 如果你的 App 最低支持 Android 11,那就直接用 BiometricPrompt 的新 API,别再用旧的了。如果还要兼容 Android 10 及以下,记得做版本判断。
嗯,关于 Android 11 的适配,核心就是这些。实际项目中你可能会遇到各种奇怪的问题,比如某些国产手机对白名单的支持不完整。我的经验是:多测试,特别是不同厂商的设备,踩坑了再回来看看这篇文章,应该能帮你省不少时间。