7

我在一家生产多个应用程序的公司工作,并非所有这些应用程序都具有相同的签名或更多类似的签名,我们目前至少有 5-6 个应用程序证书。

我们试图创建一种机制,使同一设备上的所有公司的应用程序共享相同的,例如如果用户从市场应用程序A安装并且没有安装应用程序,则会生成一个新的ID,如果他现在安装了应用程序A,应用程序 B 应该与应用程序 A 具有相同的 id(id 只是生成的 UUID 类型 #4)等...

我们目前正在使用广播,只有获得我们许可的应用程序才能接收该广播并使用另一个广播发回 id(这次是明确的)。广播和响应受到我们的签名级别许可的保护,这当然无济于事,因为我们有多个签名。

我试图编写一个意图广播和恢复,它可以拥有自己的保护机制,不仅限于一个签名,而是几个签名,问题是像 Binder.getSenderUID() 这样的东西不适用于广播,我得到了我的自己的uid。看起来我无法获得我的 snder 的身份,除非他自己在意图中写下他的 id,这不是我可以信任的,因为它很容易被伪造。使用加密需要应用程序附带一个密钥,这再次不受保护,转向服务器进行验证需要太多时间,而且在移动设备上不能保证成功,因为不能 100% 确定周围有网络。

任何人都知道如何从一个应用程序获取验证\安全消息到另一个应用程序?(我所有的应用程序,但可能有不同的签名)。

4

4 回答 4

6

和往常一样,这里有一个具有挑战性的问题,如果有的话,我从来没有得到过正确的答案!回答,所以我被迫自己找到它。

Intents 的问题在于不可能获取发送者,因为它们与网络中的多播并行,其中发送者的地址并不重要。

如果我希望获得 snder 的 UID,即使他是本地的,我也需要进行“远程”进程,而不是使用广播 IPC,我需要将 AIDL 与 IBIinder 实现一起使用。一旦我有一个 Binder 对象,我可以在我的服务中调用 getCallingUid() 并获取调用者的 uid,这将允许我要求 PackageManager 给我它的公共证书(不询问进程本身,我询问操作系统)并进行比较它是我在apk中提前准备的一组证书。

另一端的调用应用程序(向我发送它的 ID 的另一个进程)只需使用 bindService(service, conn, flags) 方法绑定到我。这种方法的缺点当然是耗时的过程,Bind 需要时间,它是一个通过内核的异步调用,不如绑定到本地服务快。此外,由于我可能有多个应用程序,我需要同步访问我的内部 ID,因此只有第一个没有失败的绑定调用才会为我设置和 ID。我仍然需要检查是否可以使用防止多线程问题的 Messanger 方法。

希望这对其他人有帮助。

于 2013-03-24T13:01:19.197 回答
2

抱歉迟了回应...

绑定需要时间,更重要的是,它是异步的。但是,有一种方法可以进行同步绑定 - 当然,假设您尝试联系的服务当时已经启动。对于 BroadcastReceiver(本质上是异步的,因此不能使用普通的 bindService),Android 允许这样做更多,BroadcastReceiver 有一个“peekService”方法。

如果你想在不收听广播的情况下使用它,你可以这样做:

final IBinder[] b = new IBinder[1];
new BroadcastReceiver() { 
    public void onReceive(Context context, Intent intent) {
        b[0] = peekService(context, intent);
    }
}.onReceiver(context, intent);

IMyInterface i = IMyInterface.Stub.asInterface(b[0);

请注意,您没有绑定到服务,因此请务必查看每次使用情况。

于 2014-03-26T08:03:14.243 回答
0

如前所述,绑定可能是最好的解决方案。但是,您可以考虑切换到 Activity 而不是 BroadcastReceiver 然后您可以使用getCallingActivity(),假设您使用startActivityForResult().

如下声明您的 Activity 以使其像 BroadcastReceiver 一样“静默”:

<activity
    android:name=".FauxReceiver"
    android:theme="@android:style/Theme.NoDisplay" 
    android:excludeFromRecents="true"
    android:noHistory="true"
>
    <intent-filter>
        ...
    </intent-filter>
</activity>

启示:如何获取 Intent 的发送者?

于 2014-07-04T10:16:38.097 回答
-2

我正在寻找一种方法来验证发送我的意图过滤器接收到的意图的应用程序的包名称。我的应用程序中处理意图过滤器的活动要求意图发送者在 Intent Extras 字段中包含他们的进程 ID。然后我的接收活动可以从 ActivityManager 中获取关联的应用程序包名称。

这是我在通过 StackOverflow 移动时发现的一些示例代码。

两个应用程序所需的常量

public static final String EXTRA_APP_ID;
public static final String ACTION_VERIFY = "com.example.receivingapp.action.VERIFY";

通话活动

    Intent verifyIntent = new Intent();
    verifyIntent.setAction(Consts.ACTION_VERIFY);
    verifyIntent.putExtra(EXTRA_APP_ID, android.os.Process.myPid());
    // Verify that the intent will resolve to an activity
    if (verifyIntent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(verifyIntent, Consts.REQUEST_VERIFY);
    } else {
       Log.d(TAG, "Application not found.");
    }

接收应用程序

显现

        <activity
            android:name="com.example.receivingapp.ReceivingActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="com.example.receivingapp.VERIFY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

接收活动

if (getIntent().hasExtra(OnyxCoreConsts.EXTRA_APP_ID)) {
    string appName = null;  
    // Resolve intent
    if (getIntent().getAction().equals(ACTION_VERIFY) {    
         int appPid = getIntent().getIntExtra(EXTRA_APP_ID, -1);
         if (-1 != mAppPid) {
             appName = Utils.getAppNameByPID(mContext, mAppPid);
         }
         if (null != appName && !"".equalsIgnoreCase(appName)) {
              // Do something with the application package name
         }
    }
}

实用程序类

public static String getAppNameByPID(Context context, int pid){
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
            if (processInfo.pid == pid) {
                return processInfo.processName;
            }
        }
        return "";
    }
于 2014-11-12T00:21:41.937 回答