您的应用包含公开的Google Cloud Platform(GCP)API密钥。有关详细信息,请参阅此Google帮助中心文章。

时间:2019-07-04 14:41:40

标签: android google-cloud-platform

我的密钥受程序包名称和SHA1限制,但Google Play商店仍显示此警告。

知道为什么会这样显示。我在build.gradle文件中定义了我的API密钥,并从那里开始使用它。

8 个答案:

答案 0 :(得分:3)

有Google Play广告吗?看来,至少从8-1-19开始,触发此操作的api键已嵌入完整的Google Play服务广告库中。那是-

implementation 'com.google.android.gms:play-services-ads:18.1.1'

触发警报,但是

implementation 'com.google.android.gms:play-services-ads-lite:18.1.1'

其中removes some code that already exists in the play store没有。错误本身引用了一种混淆的方法,我在apk中将其跟踪到:

com/google/android/gms/internal/ads/[obfuscatedstring]/<clinit>()

这似乎设置了一堆常量。其中之一称为gads:safe_browsing:api_key

以防万一我错了,而且不是每个人的代码,我也不会在这里复制它,但是在我看来,它肯定像是一个可能触发问题的GCP钥匙。它是40个字符,可以在Internet上的其他地方找到相同的密钥。

我的猜测是,如果您使用的是play-services-ads库(而不是Firebase库),则可能是看到此字符串并发出了警报。

答案 1 :(得分:2)

对不起,这里的游戏有点晚了...

请按照以下步骤操作:

  1. Firebase console将帮助您下载google-services.json。此外,大多数API的快速入门指南均包含生成此文件的说明。下载完google-services.json文件后,请将其复制到Android Studio项目的app /文件夹中,如果使用的是多种构建类型,则将其复制到app / src / {build_type}文件夹中。
  2. Google Cloud Console将通过选择在Firebase控制台中创建的项目来帮助您在API库部分启用GCP(例如:Places API,Map SDK for android等)。
  3. 您可以通过以下方式获取api密钥:

    activity.getResources()。getString(R.string.google_api_key);

用于获取API密钥的字符串密钥名称为“ google_api_key”。

仅供参考,您将解析google-services.json文件并将其值添加到xml(路径:app / build / generated / res / google / services / {build_type} /values/values.xml)中访问:https://developers.google.com/android/guides/google-services-plugin

答案 2 :(得分:0)

您不应直接在build.gradle文件中定义API密钥。替代方法可以是将您的Firebase API密钥上载到您自己的服务器(您可以使用微小的Web db或MY sql)。并在需要时从您的服务器调用API密钥并使用它。在这种情况下,应遵循以下一些良好做法。有关更多详细信息,请参见this

  • 请勿将API密钥直接嵌入代码中。内嵌的API密钥 该代码可能会意外地向公众公开。例如,您可能 忘记从共享代码中删除密钥。代替 将API密钥嵌入到应用程序中,并将其存储在 环境变量或应用程序外部文件中 源代码树。

  • 请勿将API密钥存储在应用程序源代码树内的文件中。 如果您将API密钥存储在文件中,请将文件保留在应用程序的文件之外 源代码树,以确保您的密钥不会出现在源代码控制系统中。这在以下情况下尤其重要 您使用诸如GitHub之类的公共源代码管理系统。

  • 设置应用程序和API密钥限制。通过添加限制, 您可以减少遭到破坏的API密钥的影响。

  • 删除不需要的API密钥,以最大程度地减少遭受攻击的可能性。

  • 定期重新生成您的API密钥。您可以重新生成API密钥 在“凭据”页面中,单击每个密钥的“重新生成密钥”。 然后,更新您的应用程序以使用新生成的密钥。您的 生成后,旧密钥将继续工作24小时 替换键。

  • 在公开发布代码之前,请先对其进行检查。确保您的代码 在您之前不包含API密钥或任何其他私人信息 使您的代码公开可用。

答案 3 :(得分:0)

您可以通过将密钥分成四个部分来消除此警告

public static final String API_KEY_PART_1 = "Asdsdfdd-";

public static final String API_KEY_PART_2 = "dfsFdsdsFdd";

public static final String API_KEY_PART_3 = "Pgdhs_SfSfs";

public static final String API_KEY_PART_4 = "fdfDDSD";

并通过连接字符串使用它

.attest(nonce.getBytes(), Constants.API_KEY_PART_1+Constants.API_KEY_PART_2+Constants.API_KEY_PART_3+Constants.API_KEY_PART_4)

注意:确保将API密钥限制为仅“应用程序访问”。否则,如果有人反编译您的apk并使用您的api密钥,则可能会增加您的帐单。

使用SHA和软件包名称click here来恢复API密钥,以获取详细信息

答案 4 :(得分:0)

抱歉,有些研究发现我为此问题找到了 适当的解决方法 后,我的先前回答只是绕过警告而已,有点晚了

您可以从Google json文件获取api密钥。 解析google-services.json文件并将其值添加到xml,您可以通过Java代码click here中的android资源访问json的所有元素作为

以下是从json文件访问google api密钥的示例:

activity.getResources().getString(R.string.google_api_key);

答案 5 :(得分:0)

按照google的建议,要进行限制,例如指定软件包名称以及SHA-1密钥。

已在此处进行了说明:https://cloud.google.com/docs/authentication/api-keys#securing_an_api_key

现在,这里的问题是,无论您执行什么操作,API密钥都将最终出现在代码库中,即,如果您在代码库外部(通过某些属性文件)将其指定,但是在构建阶段(通过整个密钥对于正在反编译您的代码的人是可见的,因为它现在已成为BuildConfig类文件的一部分),或者您将其拆分并在代码库中进行串联(拆分密钥仍然可见,任何人都可以通过查看用法来对其进行级联以获得最终密钥通过反编译的apk)。

  

拆分键版本将在Play控制台中摆脱警告,但该键仍处于公开状态。

因此,我建议的解决方案是对API密钥进行编码,并将其传递给代码库。在使用前,您需要将其解码回去。

一个非常简单的示例可以是:

  

请使用更好的编码算法,而不要使用此算法,这仅用于演示目的。在这里,我们使用Base64编码。

import android.util.Base64

fun main() {
   // API Key = "123456ABC"
   val myEncodedApiKey = "MTIzNDU2QUJD" // Should be passed via BuildConfig
   val decodedApiKey = Base64.decode(myEncodedApiKey, Base64.DEFAULT)

   // Now use `decodedApiKey` in your codebase.
   val decodedApiKeyString = String(decodedApiKey)
}

为什么这样更好?

  1. 您的密钥与GCP项目中的密钥不完全相同。
  2. Play控制台在扫描您的代码库时,无法将其与GCP项目API密钥匹配。因此没有警告。

更新(使用API​​密钥使用google-services.json文件的说明):

使用来自google-services.json的API密钥的解决方案不是很有效。如果您连接Firebase帐户,通常会生成google-services.json文件。在那里定义的API密钥具有不同的限制模型。您在GCP项目中定义的密码是不同的,它允许您传入程序包名称和SHA-1密钥,并且仅限于特定种类的API访问,例如仅Youtube访问。因此,如果要使用google-services.json中的API密钥,那么您实际上就不会使用在GCP帐户中设置的限制。 GCP帐户不会生成google-services.json文件。

这里是Google的官方文档,用于设置使用GCP项目定义的API密钥的Youtube API,并且在文档中提到将密钥直接放入代码中。 (无论如何,这都是错的,因为它是Google所为。)

https://developers.google.com/youtube/android/player/setup

在任何文档中都没有地方提到使用google-services.json文件来检索API密钥。

答案 6 :(得分:0)

可能已经晚了,但会帮助一些人,

fire-base json配置文件与google之间没有链接 地图集成API密钥

Firebase澄清

并且仅当您将Firebase集成到应用程序中时,它要求将json配置放入代码中,这是将应用程序与Firebase连接的唯一方法。

但是对于Google Maps来说,将它放在您的应用程序中完全是另外一回事,它为您提供了将代码放置在其他任何地方但不是硬编码或保持原样的键,

解决方案:

我将NishantSahil Arora的两种解决方案结合起来,将密钥编码为其他内容,并将其拆分为几部分,以使其难以解码,我正在拆分在这四个部分中,您可以感觉良好:

为您解码ApiKey

        // getEncodedApiKey result encoded key,
        // splitted into four the part
        String thePartOne = "encodedPartOneMaybe";
        String thePartTwo = "encodedPartNextMaybe";
        String thePartThree = "encodedPartNextMaybe";
        String thePartFour = "encodedPartLast";

        public String getSplitedDecodedApiKey(){

            return new String(
                    Base64.decode(
                            Base64.decode(
                                        thePartOne +
                                            thePartTwo +
                                            thePartThree +
                                            thePartFour ,
                                    Base64.DEFAULT),
                            Base64.DEFAULT));
        }

编码您的ApiKey

        //just to encode the string before splitting into the pieces
        //and remove this method from the source code
        public void getEncodedApiKey(){

            String plainApiKey = "xiosdflsghdfkj"; //
            String encodedApiKey = new String(
                    Base64.encode(
                            Base64.encode(plainApiKey.getBytes(),
                                    Base64.DEFAULT),
                            Base64.DEFAULT));
            Log.i(TAG, "getEncodedApiKey: " + encodedApiKey);
        }

答案 7 :(得分:0)

在我使用Google api密钥初始化Youtube Player的情况下,长期存在相同的问题。

即使使用SHA和Package名称限制了API密钥,它也没有消失。

但是,在迁移到androidX后,Google Play控制台中的安全警报已消失。