私がやろうとしているのは、デバイスにインストールされた 2 つのアプリケーション間で軽量で安全なIPC プロトコルを実装することです。Serviceクライアント アプリは、サービス アプリで実行されているコマンドとクエリを送信し、計算結果を受け取ることができる必要があります。
アプリの関係:両方のアプリのソース コードは私の管理下にありますが、アプリの署名は異なります (交渉不可)。
セキュリティ要件:サービス アプリは、そのサービスを単一のクライアントに提供する必要があります。クライアントのアプリケーション ID (パッケージ名) は既知で一定です。
試したこと:双方向Messenger通信方式で IPC を実装しようとしました (このブログ投稿と同様)。このアプローチは問題なく機能しますが、大きな問題が 1 つUIDあります。クライアントを取得する方法が見つからないため、セキュリティ要件を満たすことができません。
Serviceサービス アプリケーションの次のコードについて考えてみましょう。
// This messenger will be used by the clients of this service in order to send commands
private Messenger inboxMessenger = new Messenger(new Handler() {
    @Override
    public void handleMessage(Message msg)
        // TODO: verify the identity of the client
        switch (msg.what) {
            case MSG_GET_DATA:
                returnDataToClient(msg.replyTo);
                break;
        }
    }
});
ここでの考え方は、クライアント アプリがメッセージを thisServiceに送信するときに、ローカルの「コールバック」MessengerをreplyTosent のメンバーに入れるというものMessageです。次の状態のドキュメントMessenger:
注: 下の実装は、通信を実行するために使用される Binder の単純なラッパーです。
だから私はどうにかして返されたBinderMessenger#getBinder()をクライアントのUIDにマップできると思っていましたが、現在問題が発生しています:
- Messenger#getBinder()キャストできないIBinderを返します- Binder
- クライアントの への参照を取得できたとしてもBinder、メソッドBinder#getCallingUid()はstatic引数を受け入れません...
したがって、この特定の実装を安全に機能させるには、クライアントによって作成された特定のコンテンツまたは特定UIDのコンテンツに基づいて呼び出し元を取得する方法を見つける必要があります。Android のセキュリティ アーキテクチャは を中心に構築されているため、(またはパッケージ名) へのマッピングへの直接的なアプローチがないのは奇妙に思えます...では、どうすればこれを行うことができますか?MessageMessengerBindersBindersUIDs
おまけの質問: AIDL を除いて、Android で上記の要件を満たす IPC 手法は他にありますか?