如何让Android SafetyNetClient.Attest适配安卓应用限制的API密钥?
为什么限制API密钥为仅安卓应用后,SafetyNet Attest调用会失败
问题根源
当你把API密钥限制为仅安卓应用使用时,Google的API服务会额外验证请求来源的应用包名和SHA-1证书指纹是否与你在Google Cloud控制台配置的完全一致。你的mSafetyNetClient.attest(nonce, apiKey)调用失效,大概率是因为以下两种情况之一:
- 请求没有正确携带应用的包名/签名信息(不过
SafetyNetClient.attest通常会自动从应用上下文获取这些信息); - 你在Cloud控制台配置的包名或SHA-1,和实际测试的应用不匹配。
适配安卓应用限制的解决步骤
按以下顺序操作,就能解决问题:
1. 核对Google Cloud控制台的配置
登录Google Cloud控制台,找到你的SafetyNet API密钥,仔细检查:
- 在「应用限制」选项中,是否选择了「安卓应用」;
- 是否添加了正确的应用包名(要和
AndroidManifest.xml里的package属性完全一致); - 是否添加了用于签名应用的SHA-1证书指纹。注意:调试包和发布包使用的证书不同,如果你用调试APK测试,必须添加调试证书的SHA-1,不能只加发布版的。
2. 确认应用实际的包名和SHA-1
如果你不确定正确的包名和SHA-1,可以直接从应用获取:
- 包名:查看
AndroidManifest.xml里的package属性,或者用Android Studio的「应用检查」工具查看运行中应用的包名; - SHA-1指纹:在Android Studio右侧打开Gradle面板,找到你的app模块 →
Tasks→android→ 运行signingReport任务,会输出调试和发布两种变体的SHA-1值。
3. 添加错误日志定位具体问题
修改你的attest调用代码,捕获失败详情,这能帮你精准找到问题所在:
mSafetyNetClient.attest(nonce, apiKey) .addOnSuccessListener(safetyNetResult -> { // 处理成功的验证结果 }) .addOnFailureListener(exception -> { Log.e("SafetyNetDebug", "验证失败:" + exception.getLocalizedMessage()); // 常见错误包括「API密钥对当前应用无效」(包名/SHA-1不匹配)或「权限被拒绝」(API密钥限制配置错误) });
4. 确认依赖和权限配置正确
检查你的app模块build.gradle是否添加了正确的SafetyNet依赖:
implementation "com.google.android.gms:play-services-safetynet:17.0.0"
同时确保AndroidManifest.xml中声明了INTERNET权限(验证请求需要连接Google服务器,这个权限是必须的):
<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者RichyDavisWindow3
相关产品推荐
相关产品推荐

