按照最佳做法正确地将API密钥存储在抖动中

Phi*_*tua 10 dart flutter

如果我想将代码推送到github上,这是在flutter中添加秘密API密钥的正确方法(最佳实践)。我已经制作了一个使用API​​的简单应用程序,但是我以粗鲁的方式使用了该密钥,只是为了测试该应用程序是否正常工作。通常,根据我在后端开发应用程序的经验,密钥存储在某个位置和其他文件中,然后将其简单地导入到需要的所需文件中,API_KEY并将文件中的.gitignore文件排除在外。

到目前为止,我还实现了这种方法:

文件夹树

-lib
  -auth
    -keys.dart
    -secrets.json 
Run Code Online (Sandbox Code Playgroud)

secrets.json

在这里,我将添加,KEY.gitignore在推送代码时指定此文件被排除在github中之外。

//Add API KEY HERE
{
  "api_key": "ee4444444a095fc613c5189b2"
}
Run Code Online (Sandbox Code Playgroud)

keys.dart

import 'dart:async' show Future;
import 'dart:convert' show json;
import 'package:flutter/services.dart' show rootBundle;


class Secret {
  final String apikey;

  Secret({this.apikey=""});

  factory Secret.fromJson(Map<String, dynamic>jsonMap){
    return new Secret(apikey:jsonMap["api_key"]);
  }
}


class SecretLoader {
  final String secretPath;

  SecretLoader({this.secretPath});
  Future<Secret> load() {
    return rootBundle.loadStructuredData<Secret>(this.secretPath,
            (jsonStr) async {
          final secret = Secret.fromJson(json.decode(jsonStr));
          return secret;

        });
  }
}
Run Code Online (Sandbox Code Playgroud)

我觉得这种方法太多了。我希望获得更好方法的建议。

gen*_*ser 21

API 密钥必须进行硬编码。

为什么?

因为如果没有外部源的密钥,就不可能从外部源检索密钥,并且如果没有应用程序中的密钥,您就无法将其安全地存储在操作系统级别。

例子

当您将应用程序连接到 Firebase 项目或 Google Cloud 服务器时,您基本上使用硬编码的 API 密钥进行身份验证,该密钥是您在启动云项目时下载到应用程序中的(了解更多)。

安全

保护您的关键资产有两个重要步骤:

  1. 让您的密钥不受版本控制
  2. 使用混淆使攻击者难以对您的应用程序进行逆向工程并泄露您的 API 密钥。

IMO,这些是您可以采取的唯一步骤来保护您的应用程序 API 密钥。


Noo*_*les 14

编辑:看看下面 J. Saw 的评论。

编辑 2:底部描述的问题已在firebase-config 19.0.2.

使用Firebase Remote Config. 在 Firebase 控制台内的菜单内,向下滚动到Grow,然后Remote Config。您可以在此处添加带有值的参数。完成后不要忘记发布更改。这有点微妙。

在此处输入图片说明

现在为 Flutter安装firebase_remote_config

导入所有内容后,您可以使用以下代码检索您的值:

RemoteConfig remoteConfig = await RemoteConfig.instance;
await remoteConfig.fetch(expiration: Duration(hours: 1));
await remoteConfig.activateFetched();

remoteConfig.getValue('key').asString();
Run Code Online (Sandbox Code Playgroud)

这样,API 密钥或令牌永远不会成为您的应用程序的一部分。

注意:当前存在一个问题,您会收到一条警告,指出未设置应用程序的名称,但这不会影响功能。

  • 根据 Firebase:“不要在远程配置参数键或参数值中存储机密数据。可以对项目的远程配置设置中存储的任何参数键或值进行解码。” (https://firebase.google.com/docs/remote-config) (22认同)
  • 我喜欢这个策略。但是,您有像 https://pub.dev/packages/google_maps_flutter#getting-started 这样的文档,告诉人们将 API KEY 放在“AndroidManifest.xml”或“AppDelegate.m”中。这不是不好的做法吗?应如何替代这一策略? (4认同)
  • **这是一个糟糕的答案**,因为为了连接到 Firebase 项目,您必须首先下载硬编码的 API_Key。换句话说,这种做法毫无意义且具有误导性。https://firebase.google.com/docs/projects/api-keys#find-api-keys (3认同)

Rol*_*iza 10

对于安全存储,您必须依赖相应的原生平台,iO 和 Android 都提供了一种安全存储密钥的机制。你可以自己实现,使用flutter通道来获取和存储key。可以在此处阅读有关此机制的信息:

安卓密钥库

iOS 钥匙串

此外,您可以使用这个flutter 插件,它使用上面提到的服务并提供一个 dart 对象来访问安全存储。

  • 这没有帮助,因为您在某个时候将 API Secret 放入代码中,并且反编译 APK 仍然会泄露该 Secret! (7认同)

Gai*_*inz 5

如前所述,如果密钥是秘密并且您想保护它,那么就不要将其放在客户端应用程序中。该应用程序可以被反编译,并且可以为愿意瞄准您的客户的人提取密钥。

我会将与此 API 通信的任务委托给您的应用程序服务器。您可以将密钥放入服务器中,让服务器与此外部 API 进行通信,并将响应转发给客户端。

编辑:另一种不太安全但更方便的方法是使用 proguard 之类的东西来混淆代码。有关 android 应用程序上的 flutter 指令,请参阅此页面:https://flutter.io/android-release/

  • 但是,如果您从自己的服务器请求 API,那么每个人都可以做到这一点,只要他们知道可以再次从您的代码中检索的 URI。 (18认同)
  • 我不想为此投入额外的时间构建后端服务器,我做了研究并发现了 android 在使用 java 构建它时如何处理这个问题:(/sf/ask/1019969261/ -用于在应用程序中存储和保护私有 api 密钥)。flutter 必须有一种方法来处理这个问题。也在这里https://github.com/codepath/android_guides/wiki/Storing-Secret-Keys-in-Android (2认同)

归档时间:

查看次数:

3769 次

最近记录:

6 年,4 月 前