2013-03-20 29 views
5

Tôi làm việc trong một công ty sản xuất nhiều ứng dụng, không phải tất cả các ứng dụng đó có cùng chữ ký hoặc giống như chúng tôi có ít nhất 5-6 chứng chỉ ứng dụng trong thời gian này.android: xác thực danh tính của người gửi ý định

Chúng tôi đã cố gắng tạo cơ chế trong đó tất cả ứng dụng của companie trên cùng một thiết bị dùng chung là, Ví dụ: nếu người dùng cài đặt từ ứng dụng A thị trường và không cài đặt ứng dụng, ID mới sẽ được tạo, nếu bây giờ anh ấy cài đặt ứng dụng A, ứng dụng B phải có cùng id như ứng dụng A (id chỉ là một loại UUID được tạo # 4) v.v.

Chúng tôi đang sử dụng chương trình phát sóng vào lúc này và chỉ những ứng dụng có sự cho phép của chúng tôi mới có thể nhận được phát sóng và gửi lại id với một chương trình phát sóng khác (rõ ràng lần này). Phát sóng và các phản hồi được bảo vệ với sự cho phép của chúng tôi với cấp độ chữ ký, điều này tất nhiên là không giúp ích gì vì chúng tôi có nhiều chữ ký.

Tôi đã cố gắng viết một mục đích phát sóng và khôi phục có thể có cơ chế bảo vệ riêng sẽ không bị giới hạn chỉ một chữ ký nhưng một số vấn đề là những thứ như Binder.getSenderUID() không hoạt động cho chương trình phát sóng và tôi có uid của riêng tôi. có vẻ như tôi không có cách nào để có được danh tính của snder của tôi, trừ khi bản thân ông viết id của mình trong mục đích, đó là không cái gì tôi có thể tin tưởng vì nó có thể dễ dàng giả mạo. Sử dụng mã hóa yêu cầu các ứng dụng đi kèm với khóa không được bảo mật một lần nữa, chuyển sang máy chủ để xác thực mất quá nhiều thời gian và trên thiết bị di động không đảm bảo thành công vì không chắc chắn có mạng.

Bất cứ ai cũng có bất kỳ ý tưởng làm thế nào người ta có thể nhận được một thông báo hợp lệ \ an toàn từ một ứng dụng khác? (Tất cả các ứng dụng của tôi nhưng có thể có chữ ký khác nhau).

Trả lời

2

Xin lỗi vì trả lời muộn ...

Ràng buộc mất thời gian và quan trọng hơn là không đồng bộ. Tuy nhiên, có một cách để thực hiện một ràng buộc đồng bộ - giả định tất nhiên dịch vụ mà bạn cố gắng liên lạc đã được bắt đầu vào thời điểm đó. Android cho phép điều này nhiều hơn cho BroadcastReceivers (không đồng bộ về bản chất và do đó không thể sử dụng bindService bình thường) BroadcastReceiver có phương thức "peekService".

Nếu bạn muốn sử dụng nó mà không nghe một phát sóng, bạn có thể bằng cách làm:

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); 

lưu ý rằng bạn không liên kết với các dịch vụ, vì vậy hãy chắc chắn để lén nhìn vào mỗi lần sử dụng.

+0

đây là một hack, bnut này là damn tốt, còn tôi giả định các dịch vụ phải ở địa phương, tuy nhiên như xa như tôi biết, BR nên nhận được tin nhắn từ dịch vụ và gửi lại hoặc gửi cho hoạt động bằng ý định, nó không có nghĩa là ràng buộc với một dịch vụ ... do đó, việc có phương pháp đó thực sự vi phạm ý tưởng của một ... – codeScriber

4

Như mọi khi với một câu hỏi đầy thách thức ở đây tôi không bao giờ có được một thích hợp, nếu BẤT K!! ' câu trả lời, vì vậy tôi buộc phải tự tìm ra nó.

Sự cố với Mục đích là không thể nhận người gửi vì chúng song song với mulicast trong mạng nơi có địa chỉ của người gửi không quan trọng.

Nếu tôi muốn nhận được UID của snder, tôi cần thực hiện quy trình "từ xa" ngay cả khi người đó ở địa phương, thay vì sử dụng IPC phát sóng, tôi cần sử dụng AIDL với việc triển khai IBInder. Khi tôi có đối tượng Binder, tôi có thể gọi dịch vụ getCallingUid() và nhận được uid của người gọi, điều này sẽ cho phép tôi hỏi PackageManager cung cấp cho tôi chứng chỉ công cộng (không hỏi quá trình, tôi hỏi hệ điều hành) và so sánh nó với một bộ chứng chỉ tôi đã chuẩn bị trước trong gói ứng dụng.

Ứng dụng gọi ở phía bên kia (quy trình khác gửi cho tôi ID của nó) chỉ cần sử dụng phương thức bindService (dịch vụ, conn, cờ) để liên kết với tôi. Những bất lợi của phương pháp này là ofcourse quá trình tốn thời gian, Bind mất thời gian, đó là một cuộc gọi async mà đi qua hạt nhân và không nhanh như ràng buộc với một dịch vụ địa phương. Hơn nữa kể từ khi tôi có thể có một số ứng dụng tôi cần phải đồng bộ hóa truy cập ID nội bộ của tôi vì vậy chỉ có cuộc gọi ràng buộc đầu tiên mà không thất bại sẽ thiết lập và ID cho tôi. Tôi vẫn cần phải kiểm tra xem tôi có thể sử dụng phương pháp Messanger ngăn chặn các vấn đề đa luồng.

Hy vọng điều này sẽ giúp người khác.

0

Như đã nêu, ràng buộc có lẽ là giải pháp tốt nhất cho việc này. Tuy nhiên, bạn có thể xem xét chuyển sang một Hoạt động thay vì một BroadcastReceiver sau đó bạn có thể sử dụng getCallingActivity(), giả sử bạn đã khởi chạy với startActivityForResult().

Khai báo bạn Hoạt động như sau để làm cho nó "im lặng" như một BroadcastReceiver:

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

Inspiration: How to get the sender of an Intent?

+1

Chúng tôi đang làm việc trên thư viện để xác minh người gửi và người nhận 'Intent' sử dụng kỹ thuật này để bắt đầu, vì nó đơn giản nhất. Bạn có thể tìm hiểu thêm tại đây https://dev.guardianproject.info/projects/trustedintents/wiki –

+0

@ Hans-ChristophSteiner Có vẻ tốt. Thật kỳ lạ là họ không bao gồm người gửi trong tất cả các lời gọi Intent (không chỉ những người yêu cầu kết quả) vì chi phí có lẽ sẽ là tối thiểu. –

-1

tôi đang tìm kiếm một cách để xác minh tên gói của ứng dụng đó đã gửi ý định nhận được bởi bộ lọc ý định của tôi. Hoạt động đó trong ứng dụng của tôi xử lý bộ lọc ý định yêu cầu người gửi ý định bao gồm id tiến trình của họ trong trường Intent Extras. Sau đó hoạt động nhận của tôi có thể lấy tên gói ứng dụng được liên kết từ ActivityManager.

Dưới đây là một số mã ví dụ tôi đã tìm thấy trong khi chuyển qua StackOverflow.

Constants cần thiết cho cả hai Apps

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

Calling Hoạt động

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."); 
    } 

Nhận App

Manifest

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

ReceivingActivity

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

Utils lớp

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 ""; 
    } 
Các vấn đề liên quan