Sharing keystore between multiple apps - android

I am developing an SDK/API that will be used by apps not written by me.
I want my code to generate a private key once and store it on the device.
This key should be unique per device, I don't mind it being erased on factory reset, and I don't need to extract it from the device.
Sounds an ideal case for the KeyStore (preferably with a StrongBox).
I do want, though, different apps to use the same key to sign (or ask my API to do so)
I could not answer two concerns:
If my API is a library linked (statically) into the app, different apps using my code wouldn't be able to use the key, because the keystore requires
If I package my API as a separate android app, and have the other apps use it using Intents, I'll have to have the user install it manually, because as far as I could tell, Android/Play does not allow for dependencies between apps.
What is the most graceful way to resolve this situation?

Related

Is it possible to share Android Keystore between different Android Apps signed with different signatures?

Use Case: Share credentials(example private key) stored in Android Keystore among different applications on the same device signed with different signatures.
I was able to achieve it using the following approach (but I don’t think it is the correct way of doing it):-
Signed the application with the same certificate.
I declared my applications with the same sharedUserId, like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mydomains.myapp"
android:sharedUserId="com.mydomains.shared.user.id"
android:sharedUserLabel="#string/appName">
Followed this post on StackOverflow: How to securely share data between two or more applications in android?
Problems:-
sharedUserId is a deprecated property.
It requires the same signature for the apps.
Is there any other way in which we can share credentials stored in Android Keystore b/w apps on the same device?
PS: In my usecase the Android Apps can belong to different organizations but can share a common SDK.
If I understand your question correctly, I believe the KeyChain API would be an appropriate implementation for this use case which can be used to share between apps.
For more details: https://developer.android.com/training/articles/keystore#WhichShouldIUse
https://developer.android.com/reference/android/security/KeyChain
Hope this helps!

How to secure google API keys

I have been doing some security testing on an Android app. One thing I am trying to wrap my head around is API key security; particularly google Places and Maps keys. There are lots of posts that talk about the options, namely compiling keys into source, placing them in resource files, compiling them into a shared library, etc. In my particular case, the Maps key is in the manifest file, and the Places key is in a shared library. I created a signed APK to test how hard it would be to obtain and use one of the keys. I did the following:
Reverse engineered the APK using apktool,
Opened the manifest and grabbed the Maps key,
Created a fake version of the application with the same package structure as the original containing an activity with a google map fragment,
Put the Maps key in the fake manifest,
Ran the application, which displayed the map
Then I:
Created a new class in the fake app with the same package and name as the original with code to load the shared library from /data/data/[package name],
Copied the the shared library from the reverse engineered APK to the /data/data/[package name] folder of the fake app,
Ran the fake app, which then printed out the Locations API key
So in the end, without much effort, I had both keys which I could then use in a fake version of the application.
I'm sure I must be missing something. It looks like the only option for Maps is to store the key in the manifest. What is stopping someone from doing what I did? Surely it can't just be indifference. I realize that someone would probably get caught if they tried to publish their app using a hijacked API key. However, someone could create an app and have people side load it. It would be a huge disruption for customers if the company had to change a hijacked key every time someone messed with it.
I believe you need to go through the Docs for Google API keys again. There seem to have something called restrictions that should be able to help with you ensuring that your Keys are protected and not used on some other application.
I believe that restrictions prevent a request from other domains you have not included from not being able to render.
API Key best practices
There are many way to keep your API key secure. Below links are explained that how to secure your keys.Depending on your use case you can follow one of them
Using Gradle
Using NDK
Using Server Call

Signing android application

I have Google Developer account and I published my first application.
Now I need to publish my second app. Should I sign with the same keystore of my first app.
Please let me know if I'm not clear.
Using the same keystore/key pair is fine for as many apps as you like. I have several that share a keystore/key.
Here is how you should decide if you need a separate key/keystore, in order of importance/concern:
Having more than one key or keystore requires remembering passwords and their locations along with securing them. This can be a real pain if you don't update your apps for quite some time. If you lose these, you cannot update/republish your app.
It is probably a good idea to use separate keys and the same keystore. This can reduce the likelihood that a hacker could hack both if either is ever hacked. However, this concern is minimal since this scenario is unlikely unless you have a very popular app.
If you want to "sell" any of yours apps at some point, you will need to provide a keystore and key to the buyer. Thus, the buyer will know your other app's keystore/key information if they are shared. If you would likely sell apps together, then a common key/keystore is not an issue. If you want to sell them separately, then you should probably have separate keystores and keys. HOWEVER, this is very unlikely to ever be a consideration.
Good luck!
A keystore can old multiple keys.
Use one key for one application.
Now, you can use the same keystore and add a key to it, or create another keystore.

How do most companies sign their Android Apps?

What is the best practice for an organization that will need to sign multiple Android apps?
Do we create one key and use that on all of the Android apps that we build? My initial thought is that this is a good approach.
Or, do we create a new key for each Android app?
Does anyone know how an organization like Google or Rovio handles this issue?
One of my clients uses a different key for each set of related apps. So apps that are usually used together share the same key, but unrelated apps have a different ones. They feel that segregating the keys this way is a good balance between ease of key management and minimizing exposure if a key ever gets disclosed (by a disgruntled employee, etc.).

I want to obfuscate some files in my application, how?

The apps we write will soon be enhanced by downloadable "packages" using the in-app purchase API. We would like therefore to start securing our content which we wish to allow the users to download/extract onto their memory card (so as to not use up internal memory for our large applications), however, we need to secure the files somehow so that they can't simply be taken from the SD.
Can anyone suggest some possible/simple/common techniques used to do so on Android?
You'll want to look into ProGuard, it's pretty well integrated with ADT. An easy way to get a good ProGuard config file is to create a new Android project in Eclipse, as the newer versions of ADT automatically make one for you. It is used when you right click the project and use Android Tools>Export
I'd think you'd probably want to generate a hash based on some unique device identifier and a strong key of your choosing. A unique identifier for the device can be generated using the technique discussed in this answer. Have the App transmit that hash to your server, and encrypt the package before (or as) it is sent to the user using this hash as a key. Your app will decrypt the data as it is read by generating the key on demand (the same way it was initially generated). Have a look at the MessageDigest class and the javax.crypto package in the API.

Categories

Resources