Google Play 服务返回使用非 Google 密钥签名的令牌

Posted

技术标签:

【中文标题】Google Play 服务返回使用非 Google 密钥签名的令牌【英文标题】:Google play services returning a token signed with a non-Google key 【发布时间】:2017-09-23 13:49:07 【问题描述】:

我有一个 android 客户端使用 GoogleAuthUtil.getToken(Context context, Account account, String scope) 从 Google Play 服务获取身份验证令牌。

然后将其发送到后端 (Go) 服务器,该服务器检查令牌是否由来自 https://www.googleapis.com/oauth2/v1/cert 的 Google 签名证书之一签名。为此,它需要在令牌头中查找分配给“孩子”的证书。

99% 的情况下,这工作得很好,但我经常遇到给定的“孩子”与任何已发布的 Google 证书不对应的情况,因此我无法验证令牌。

编辑:

我已经在服务器上添加了广泛的日志记录来尝试追踪这一点,并且有一些关系值得注意:

    任何给定的无效kid 仅用于单个用户。我经常在几天内看到来自同一用户的多个请求,其中给定的 kid 无效,但仅来自该用户。 提供无效kid 的用户永远不会将有效kid 用于任何请求,或任何其他kid 用于请求,即使它们相隔几天。 Afaik Google 每 24 小时左右循环一次他们的证书。 许多用户正在使用较旧的客户端版本。大多数用户会在新版本发布后的一两天内升级,但大多数证书密钥无效的用户使用的是几周前的版本。 根据我们的用户群,请求来自全球各地。 请求来自不同时期,符合我们的用户群。 请求来自一系列设备、制造商和型号。

我目前的想法是,它可能来自从 Google Play 以外的网站下载 APK 的用户,但我现在无法验证这一点。

编辑:有一个问题跟踪器,但它似乎已被标记为低优先级。如果有人遇到此问题,请在跟踪器上告知。 https://issuetracker.google.com/issues/37734997

【问题讨论】:

您可能想检查您的代码如何将 ID 保存到服务器。您还可以查看此文档 - Authenticate with a backend server,这可以帮助您将 tokenID 发送到服务器以验证完整性。希望这会有所帮助。 @Mr.Rebot 如果这是客户端的错误,它应该会影响整个令牌,但我所看到的只是一个格式良好的令牌,其中包含一个与任何不匹配的“孩子”已发布 Google 签名证书密钥。 很多安卓手机(尤其是东亚国家)没有Play Store或Google Play Services。是否有可能没有为这些用户提供适当的身份验证令牌?这支持您的想法,即这些用户没有从 Play 商店下载 APK。 您可以通过将令牌用于有目的的用途来验证令牌。您的应用是否有违法行为? @danny117 恐怕我没听懂你的意思。绝大多数情况下,发送给我们的令牌都是有效的。在不到 1% 的情况下,我们得到的令牌已由不在 Google 签名证书列表中的证书签名,因此无效。我们的应用在 Google Play 上,所以它绝对是合法的,即使不是这样,它也不会影响 Google Play 服务用来签署令牌的证书。 【参考方案1】:

有点晚了,但对于遇到相同情况的人,我建议检查您应用的Installer

使用PackageManager.getInstallerPackageName()

getInstallerPackageName (String packageName) 获取包名 安装软件包的应用程序。这确定了哪些 市场包装来自

如果值为“com.android.vending”,则应用是从 Play 商店安装的,否则处理其他供应商。

【讨论】:

以上是关于Google Play 服务返回使用非 Google 密钥签名的令牌的主要内容,如果未能解决你的问题,请参考以下文章

LogCat 消息:未找到 Google Play 服务资源。检查您的项目配置以确保包含资源

我可以为非游戏使用 Google play 游戏服务吗

Google Play Services v23 Proguard 配置

错误:“用于调用 Google Play 开发者 API 的项目 ID 尚未在 Google Play 开发者控制台中链接。”

如何为项目使用不同版本的 google-play-services 库

Proguard 使用 Google Play 服务库返回错误