Reputation: 1671
I have two Android apps, App A and App B.
Those two have to communicate with each other in a secure manner. I defined a custom permission for that in App A. App B uses that custom permission. If I set protectionLevel to "normal" than this works fine, but that does not seem really secure, as anyone could just use that permission.
The only way that this would be really secure is, if I could set protectionLevel to signature. Sadly I have the following restrictions:
Is there any way to get this to work? And if not (which I guess is the case):
What is a good way to make sure that only App B can communicate with App A?
Upvotes: 2
Views: 2127
Reputation: 418
Case 1: When App A and App B signed with different key, you can at least check the caller package name through your broadcast listener.
@Override
Public void onReceive(Context context, Intent intent) {
Uri packageNameUri = intent.getData();
String packageName = packageNameUri.getSchemeSpecificPart();
If(packageName.equals(“<App_A or App_B packageName>”){
//Access granted, execute what you need!
}
else{
//deny access
}
}
Don't forget to declare your broadcast receiver in Android manifest file:
<receiver android:name="<your_receiver_class " >
<intent-filter>
<action android:name="<give it any name>"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
Case 2: When both apps signed with the same key.
Make sure the two apps are signed with the same key and add the following attribute in the manifest file if you would like to share Linux userID as well:
android:sharedUserId="<provide dot separated name e.g. “android.shared.uid”">
One way to enforce signature based permission is to create a custom permission in the manifest as follow:
<permission android:name="org.securecom.permission" android:protectionLevel="signature"></permission>
…
<activity
android.permission="org.securecom.permission"
...
</activity>
This way, you can statically configure and enforce signature based permission to your components.
It is also possible to check dynamically through your broadcast listener:
@Override
public void onReceive(Context context, Intent intent) {
Uri packageUri = intent.getData();
String packageName = packageUri.getEncodedSchemeSpecificPart();
int flags = PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES;
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName,flags);
// verify packageInfo
} catch (NameNotFoundException e) {
// handle
}
}
I have tested the signature based permission and it works well.
Hope this helps.
Upvotes: 5