How to Hide API and Secret Keys in Android Studio?
API (Application Programming Interface) is a set of codes that helps in propagating information from one software or an application to the other. Tech companies create their software and APIs, which can be used to build new applications and features by their employees, making them private to use. However, some companies lease their APIs to third parties (can be other companies, developers, contributors) to implement features from their software in their projects, at some minimal cost and restricted use. So if you purchase or lease an API from a company, the company will provide you with an API key, which you must declare in your project to validate the API permission and access the features.
Why hide them? How can we hide them?
So it becomes crucial to hide API keys while using them to build applications as you have purchased or leased them. There are several ways of wrapping them within the application. We want to share with you an ethical way to secure your API key while building applications in Android Studio through this article. Refer to the flowchart below and try understanding the approach.
To hide a key, follow the steps below:
Step 1: Create a New Project in Android Studio
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. We demonstrated the application in Kotlin, so make sure you select Kotlin as the primary language while creating a New Project.
Step 2: Go to the .gitignore file in the projects in the menu
In the left top corner of the Android Studio IDE, you will find a menu where you can view the same project in different views. Click it and select the project option.
Select the Project option in the menu
In the project option, you will find the Gradle folder in which you need to open the .gitignore file.
Click on the .gitignore file to open it
Step 3: Check if local.properties is listed in the .gitignore file
In the .gitignore file, check if local.properties is listed. .gitignore will ignore every file listed in it during the build.
Step 4: Go to local.properties file in the gradle folder and declare the API/Secret key
In the same gradle folder, you will find the local.properties file. Open it and declare the key as shown.
Step 5: Go to build.gradle in the app > src folder and append the following Google plugin
Now go to the build.gradle file and add the below plugin in the plugins as shown.
After adding the plugin, click on the Sync Now option.
Источник
How to hide your API Key in Android
Many Android apps that interact with the cloud use a client – server architecture with the phone acting as a client and much of the heavy lifting taking place on the server. Sometimes you have control over the server, and sometimes it’s a third party who provides the data, e.g. traffic updates, stock market data, or weather information etc. Typically these third party providers use an API key as a simple authentication mechanism to grant access to these resources, and as a way to charge for their data.
Now there are lots of reasons why you might want to keep your API key safe. Obviously if you’re being charged for access to the API data then you don’t want someone to decompile your APK, find your API key, and then start using it in their own apps. It’s either going to cost you money for these stolen API calls, or worse still, create frustration for your existing users if your API suddenly stops working because the provider stops your access when it spots the increased activity. If your API key does become compromised then getting a new key out to your users is never easy. Do you revoke the old API key and switch to a new API key, potentially leaving users of earlier versions stranded? Or do you keep the old API key alive while you wait for the old users to upgrade, but run the risk of further bogus charges? Either way is not going to be 100% satisfactory, so it is best to avoid the situation completely.
[aa_image src=»https://cdn57.androidauthority.net/wp-content/uploads/2015/04/Figure2.png» alt=»Figure2″ width=»1366″ height=»673″ ]
Before we look at the options for hiding your API key, let’s look at how someone can find your API key. There are two basic types of attack, firstly by decompiling the APK to see if it is stored somewhere in the code, and secondly using a Man in the Middle (MITM) attack to see if it’s transmitted insecurely over the web. To access the network traffic the hacker needs to root their phone using something like ProxyDroid. This allows the traffic to be intercepted using the Charles Proxy tool or BurpSuite using a MITM attack.
API keys are often sent via a URL. For example, you can make a request to the Weather Underground API using the following URL,
http://api.wunderground.com/api/2ee858dd063ef50e/conditions/q/MI/Troy.json where 2ee858dd063ef50e is the API key. If you send the request via HTTP then the API key would be clearly visible to anyone doing a MITM attack. Sending it correctly via HTTPS will make it impossible to see the API key via proxying. Note I used the word “correctly”. The media is littered with examples of MITM attacks where the HTTPS was intercepted because the app accepted a fake SSL cert generated by tools like Charles Proxy rather than checking that it came from a reputable Certificate Authority (CA). We’ve also found examples where the device itself didn’t handle certs correctly and any HTTPS traffic was open to a MITM attack. You also need to be careful about where the API key lives before you assemble the HTTPS call. We’ll look at that next.
In my audits of hundreds of Android mobile apps I have seen many attempts to hide the API key. In this article we look at some of the ways developers have tried to protect your API key.
The possible options are as follows:
- In shared preferences, assets or resources folders
- Hardcoded in Java
- Using the NDK
- API key Public/private key exchange
In shared preferences, assets or resources folders
Below is an example of an API key that was found by unzipping the APK file after it was pulled off the phone and looking in the asssets folder.
The most common place I find that developers store API keys is in the shared preferences, below is a an example. It’s common practice to put APIkeys in the resources folder in the APK, which then gets stored in shared preferences after the app is first opened.
Hardcoded in Java
[aa_image src=»https://cdn57.androidauthority.net/wp-content/uploads/2015/04/Figure3.png» alt=»Figure3″ width=»1362″ height=»676″ ]
An API key is much much more likely to be found in the assets or resources folder than in the decompiled code because it’s much easier to update xml than compiled code. But it still happens regularly. Below an example of an API key found in a pharmacy app that was stored in a Constants.java file.
Using the NDK
The Android Native Devlopment Kit (NDK) allows you to write code in C/C++, and can be very useful when you’re trying to hide things like API keys. The good news is that NDK libraries can’t be decompiled making the information harder to find. The NDK compiled code can still be opened with a hexidecimal editor but by the nature of the API key they are harder to pick out in a hexidecimal editor.
You should include a call to see if the checksum matches your APK as otherwise someone can call your NDK library outside of your app to recover the password. This approach is ultimately not going to be good enough to stop someone from reading the binary. But it is a better option to consider if you have no other choice than to put the API or encryption keys on the device, for example if the backend server belongs to a third party provider. Disassembled code also rapidly becomes more difficult to understand as it gets further away from these simple helloworld examples.
Public/private API key exchange
While HTTPS securely hides the API key during transmission, retrieving the API key from the phone so the HTTPS call can be made is a real problem for developers. As we’ve seen hiding an API key is not dissimilar to how people try to hide an symmetric encryption key (see my earlier article on where to store your passwords). All these keys can be recovered using the adb backup or adb pull command and a little perseverance. So even if the hacker can’t perform a Man in the Middle attack they can still see how the call is put together and the API that’s used in the call so they can hijack your resource if it’s useful to them. We could try try to encrypt the API key on the phone but if you’re storing the encryption key on the phone, then you’re simply adding one extra step to get to the API key.
However you can use a public/private API key exchange to safeguard the API key, so it can no longer be stolen. The downside to using public/private key exchange for passwords is that the phone can’t be in airplane mode when you login as the decryption takes place on a remote server. That doesn’t apply to API keys as they’re always using network communication.
The key should first be encrypted with the public key on a remote server using your favorite library such as Google’s Keyczar. You can either store it in the res/xml folder so you can retrieve it when someone opens the app on the phone and then store it in the app’s shared preferences, or send it to the app from the remote server so it can be reused when needed. When the URL call is made the encrypted API key is sent via HTTPS and then decrypted on the server so it can be compared to the real API key. You can also use some other dynamic piece of information such as the username to make sure the encypted API key can’t itself be used as an API key. There is nothing to stop someone else from sending the same encrypted API key from a different app to defeat your efforts. You can stop these replay attacks by encrypting your API key together with a one-time only randomly generated number or GUID, known as a nonce. The nonce and API key are sent to the server for API authentication, and the API key and a new nonce are sent back to the client to be saved in the shared preferences after each login for the next use. Every generated nonce is saved when created and marked as used once it has been sent from any client.
Conclusion
What option you choose is probably going to be determined by how much control you have over the backend server. If you don’t have any control then you’re probably going to have to hide the API key using the NDK. If you do then we recommend the Public/Private encryption of the API key using nonces to prevent any replay attacks. In the next article we’ll look at the security implications of supporting earlier Android OS versions, as well as how some Android phones are more secure than others.
Источник