Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way of storing API Keys in flutter following best practises

Tags:

flutter

dart

Which is the correct way(best practice) of adding secret API keys in flutter in case I want to push the code on github. I've made a simple app that consumes an API but I used the key in a crud way just to test whether the app is working. Usually from my experience developing applications in the back-end, Keys are stored somewhere and in different file then one would simply import it to the required file that needs the API_KEY and exclude the file in .gitignore file.

So far I have also implemented this approach:

Folder tree

-lib
  -auth
    -keys.dart
    -secrets.json 

secrets.json

This is where I will add the KEY and specify this file in .gitignore to be excluded from being added in github when I push my code.

//Add API KEY HERE
{
  "api_key": "ee4444444a095fc613c5189b2"
}

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;

        });
  }
}

I feel like this approach is too much. I would like to get suggestions of a better approach.

like image 781
Philip Mutua Avatar asked Aug 17 '18 12:08

Philip Mutua


4 Answers

EDIT: Look at J. Saw's comment below.

EDIT 2: The issue in described at the bottom has been fixed in firebase-config 19.0.2.

Use Firebase Remote Config. Inside the Firebase console, inside the menu, scroll down to Grow and then Remote Config. Here you can add a parameter with a value. When you're done don't forget to publish the changes. It's kind of subtle.

enter image description here

Now install firebase_remote_config for Flutter.

After importing everything, you can retrieve your value using this code:

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

remoteConfig.getValue('key').asString();

This way, the API key or token is never part of your application.

Note: there is currently an issue where you get a warning stating the application's name is not set, but this won't affect functionality.

like image 171
Noodles Avatar answered Oct 16 '22 20:10

Noodles


For secure storage you have to rely on the corresponding native platforms, both iOs and Android provide a mechanism to securely store keys. You can implement it by yourself and use the flutter channels to obtain and store the keys. Information about this mechanism can be read here:

Android Keystore

iOs KeyChain

Also, you can use this flutter plugin, which uses the services mentioned above and provides a dart object to access the secure storage.

like image 29
Rolando Urquiza Avatar answered Oct 16 '22 21:10

Rolando Urquiza


As mentioned, if the key is a secrete and you would like to protect it then simply do not put it in the client app. The app can be de-compiled and the key can be extracted for person willing to target your client.

I would delegate the task of communicating with this API to your Application Server. You can put the key in your server and have your server communicate with this external API and relay the response to the client.

Edit: Another approach, which is less secure but more convenient is to obfuscate your code using something like proguard. See this page for flutter instruction on android app: https://flutter.io/android-release/

like image 35
Gainz Avatar answered Oct 16 '22 21:10

Gainz


API Keys must be hard coded.

Why?

Because it's impossible to retrieve the key from an external source without having a key to that source, and you can't store it securely at the OS level without having the key within the app.

Example

When you connect your app to a Firebase project or Google Cloud servers, you basically authenticate using a hard-coded API key, that you have downloaded into your app when initiating your cloud project (read more).

Security

There are two essential steps to secure your critical assets:

  1. Keep your secret keys out of version control.
  2. Use obfuscation to make it difficult for attackers to reverse engineer your application, and reveal your API Key.

IMO, those are the only steps you can take to secure your app API Key.

like image 22
genericUser Avatar answered Oct 16 '22 21:10

genericUser