2

我有两个 Android 应用程序,应用程序 A 和应用程序 B。

这两个必须以安全的方式相互通信。我在 App A 中为此定义了一个自定义权限。 App B 使用该自定义权限。如果我将 protectionLevel 设置为“正常”,则可以正常工作,但这似乎并不安全,因为任何人都可以使用该权限。

唯一真正安全的方法是,如果我可以将 protectionLevel 设置为签名。可悲的是,我有以下限制:

  • 应用 A 必须使用 Cert A 签名
  • 应用 B 必须使用 Cert B 签名
  • 应用程序 B 也可以与证书 A(表示 A 和 B)签署,但这似乎并没有让我在任何地方,也根据这个来源

有什么办法可以让它工作吗?如果不是(我猜是这样):

确保只有 App B 可以与 App A 通信的好方法是什么?

4

1 回答 1

5

案例1:当App A和App B使用不同的key签名时,你至少可以通过你的广播监听器查看调用者包名。

@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
    }
}

不要忘记在 Android 清单文件中声明您的广播接收器:

<receiver android:name="<your_receiver_class " >
    <intent-filter>
        <action android:name="<give it any name>"/>
        <data android:scheme="package"/> 
    </intent-filter>
</receiver> 

情况 2:当两个应用程序使用相同的密钥签名时。

如果您还想共享 Linux 用户 ID,请确保这两个应用程序使用相同的密钥签名并在清单文件中添加以下属性:

android:sharedUserId="<provide dot separated name e.g. “android.shared.uid”">

强制执行基于签名的权限的一种方法是在清单中创建自定义权限,如下所示:

<permission android:name="org.securecom.permission" android:protectionLevel="signature"></permission>
…
<activity
    android.permission="org.securecom.permission"
        ...
</activity>

通过这种方式,您可以静态配置和强制对组件执行基于签名的权限。

也可以通过广播监听器动态检查:

@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
    }
}

我已经测试了基于签名的权限,它运行良好。

希望这可以帮助。

于 2013-08-10T22:02:52.107 回答