Where to store API connection credentials on Android

Asked

Viewed 755 times

4

I wanted to know a suitable place to save the connection with the api (link, user and password), initially I was thinking of saving in an xml, but I believe that any user will have access to this file, being able to open and read. There is a safer way?

  • 1

    I usually do this: I create a class with an encryption algorithm and encrypt the user and password, then I take the strings generated by this algorithm and if they are variable in the class I will use, encrypted even as they are, I use the algorithm used to generate these variables to decrypt them and to open my db

  • 1

    So, you can crack the code however you want, which although obfuscated, I know you can reverse engineer, but if you don’t open the database, because the class that generated the encryption is separate, so you can’t do much without db

  • 1

    Can protect as much as it is, reverse engineering will always bring the private keys of the internal API. All applications such as Facebook, Instagram, Snapchat already have Internal API exposed on the internet. Any apktool will reveal your code, including the keys. Most applications use HMAC to authenticate and is based on the User-Agent, it is also informed the version of the application used, this influences the return as well. Snap uses AES (I can’t remember which one), with some weird padding. Plus a VPN/Network Monitor is easy to find out what is sending.

2 answers

4


"The best way to protect secrets is not to put them in the code."

Not being possible, these are some of the options where to store them:

  • In string Resources.
  • Hidden in source code.
  • Hidden in Buildconfigs.
  • Using Proguard.
  • Encrypted/masked strings.
  • Hidden in classes created using NDK.

Whatever option is chosen, it does not guarantee 100% the protection of the values stored, only makes it difficult to obtain.
A user who can "break" one, "break" the other. It’s a matter of having more or less work.

Therefore, choose the easiest to implement, use strings declared in the archive res/values/strings.xml.

<resources>
    <string name="user">[email protected]</string>
    <string name="password">dfr125NF56</string>
</resources>

References:

Note: In order to have access to the application code, if the application is distributed in Google Play, you must have a "rooted" device. This removes the possibility for most users to access the "secrets" stored in the application

2

Several applications, both for Android and IOS, require credentials for use. One way or another, you can create applications that can be used after creating an account or also applications that you don’t necessarily need to have, limiting access by you. It’s a bit, let’s say so, annoying, for the user every time they use the application, having to reinsert user name / email and password again, unless it involves money, such as the case of bank applications, etc.

On the page of safety tips Google, which references Android says the following:

In general, we recommend minimizing the frequency of requests for user credentials - to make phishing attacks more evident and reduce your likelihood of success. Instead, use a authorization token and update it.

Where possible, user names and passwords should not be stored on the device. Instead, perform authentication using the given username and password by the user and then use a short term authorization token service-specific.

I believe that using the Accountmanger is a viable option for storing credentials. The Samplesyncadapter provides an example of how to use it.

If it is not an option for you for some reason, you can resort to persistent credentials using the preference mechanism. In theory, other applications will not be able to access your preferences, as user information is not easily exposed. Furthermore, if they reverse engineer, they will not have access to this information.

Preferably using token that can be changed from time to time:

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("email", "[email protected]");
editor.putString("token", "1DCCDD82A62716194A7AEB1C79C9B");
editor.commit();

Regarding the API connection, you can choose to store in a class of constants:

public class Constants {
    public static final String APISERVER = "https://api.meusite.com/";
    public static final String TOKEN = "1DCCDD82A62716194A7AEB1C79C9B";
}

Or in a string Resource, res/values/string.xml:

<resources>
    <string name="apiserver">https://api.meusite.com/</string>
    <string name="token">1DCCDD82A62716194A7AEB1C79C9B</string>
</resources>
  • 1

    If I understand the question correctly, your answer (except for the end) escapes what was asked. The author is asking about saving API keys in APK and not about saving user-typed data.

  • @Pabloalmeida he said connections(link, user and password), so I took to the general scope in the sense of security, but giving option at the end of the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.